更有效的迭代数组列表的方法

时间:2013-11-12 14:59:50

标签: java performance arraylist

我的程序接收数千个PL / SQL函数,过程和视图,将它们保存为对象,然后将它们添加到数组列表中。我的数组列表使用以下格式存储对象:

ArrayList<PLSQLItemStore> storedList = new ArrayList<>(); 
storedList.add(new PLSQLItemStore(String, String, String,   Long            ));
storedList.add(new PLSQLItemStore(Name,   Type,   FileName, DatelastModified));

我想要做的是根据名称从数组列表中删除重复的对象。将根据其dateLastModified变量删除旧对象。我采用的方法是有一个外部循环和一个内部循环,每个对象将自己与每个其他对象进行比较,然后将名称更改为&#34;删除&#34;如果它被认为是更老的。然后程序通过数组列表向后执行最后一次传递,删除名称设置为&#34的所有对象;删除&#34;。虽然这很好,但看起来非常低效。 1000个物体将意味着需要进行1,000,000次传球。我想知道是否有人可以帮助我提高效率?感谢。

示例输入:

storedList.add(new PLSQLItemStore("a", "function", "players.sql", 1234));
storedList.add(new PLSQLItemStore("a", "function", "team.sql", 2345));
storedList.add(new PLSQLItemStore("b", "function", "toon.sql", 1111));
storedList.add(new PLSQLItemStore("c", "function", "toon.sql", 2222));
storedList.add(new PLSQLItemStore("c", "function", "toon.sql", 1243));
storedList.add(new PLSQLItemStore("d", "function", "toon.sql", 3333));

ArrayList Iterator:

for(int i = 0; i < storedList.size();i++)
{
    for(int k = 0; k < storedList.size();k++)
    {
        if (storedList.get(i).getName().equalsIgnoreCase("remove"))
        {
            System.out.println("This was already removed");
            break;
        }

        if (storedList.get(i).getName().equalsIgnoreCase(storedList.get(k).getName()) &&  // checks to see if it is valid to be removed
           !storedList.get(k).getName().equalsIgnoreCase("remove") &&
           i != k )
        {
            if(storedList.get(i).getLastModified() >= storedList.get(k).getLastModified())
            {
                storedList.get(k).setName("remove");
                System.out.println("Set To Remove");
            }
            else
            {
                System.out.println("Not Older");
            }
        }
    } 
}

删除对象的最终通行证:

System.out.println("size: " + storedList.size());
for (int i= storedList.size() - 1; i >= 0; i--)
{
    if (storedList.get(i).getName().equalsIgnoreCase("remove"))
    {
        System.out.println("removed: " + storedList.get(i).getName());

        storedList.remove(i);                
    }
}
System.out.println("size: " + storedList.size());

3 个答案:

答案 0 :(得分:0)

您需要PLSQLItemStore实施hashCodeequals方法,然后您可以使用Set删除重复项。

public class PLSQLItemStore {

    private String name;   

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 47 * hash + (this.name != null ? this.name.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final PLSQLItemStore other = (PLSQLItemStore) obj;
        if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name))     {
            return false;
        }
        return true;
    }
}

然后只做Set<PLSQLItemStore> withoutDups = new HashSet<>(storedList);

P.S。 equalshashCode由NetBeans IDE生成。

答案 1 :(得分:0)

将它们放入番石榴ArrayListMultimap<String,PLSQLItemStore>

使用PLSQLItemStore作为密钥添加每个name

完成添加后,循环遍历多图,使用List对每个Comparator<PLSQLItemStore>进行排序,然后按dateLastModified排序,并拉出每个List的最后一个条目} - 这将是最新的PLSQLItemStore

将这些条目放入另一个Map<String,PLSQLItemStore>(或List<PLSQLItemStore>,如果您不再关心该名称)并丢弃ArrayListMultimap

答案 2 :(得分:0)

根据Petr Mensik的回答,您应该实施equalshashCode。从那里,您可以将项目放入地图中。如果您遇到重复内容,则可以决定该怎么做:

Map<String, PLSQLItemStore> storeMap = new HashMap<String, PLSQLItemStore>();
for(PLSQLItemStore currentStore : storedList) {

    // See if an item exists in the map with this name
    PLSQLItemStore buffStore = storeMap.get(currentStore.getName();

    // If this value was never in the map, put it in the map and move on
    if(buffStore == null) {
        storeMap.put(currentStore.getName(), currentStore);
        continue;
    }

    // If we've gotten here, then something is in buffStore.
    // If buffStore is newer, put it in the map.  Otherwise, do nothing
    // (this might be backwards --  I didn't quite follow your logic.  
    // Feel free to correct me
    if(buffStore.getLastModified() > currentStore.getLastModified())
        storeMap.put(currentStore.getName(), currentStore);

}

您的地图无重复。由于MapCollection,因此您可以稍后在代码中迭代它:

for(PLSQLItemStore currentStore : storeMap) {
    // Do whatever you want with your items
}