首页 > 解决方案 > 用于循环的 Java 重复捕获器仍然返回欺骗

问题描述

我有一个旨在从 ArrayList 中删除重复对象的方法。对象属于自定义类 IndividualEntry,方法如下所示:

 private static ArrayList<IndividualEntry> cleanList(ArrayList<IndividualEntry> inputList){
        ArrayList<IndividualEntry> thisList = inputList;
        IndividualEntry thisEntry;
        IndividualEntry thatEntry;
        for(int i = 0; i<thisList.size();i++){
            thisEntry = thisList.get(i);
            System.out.println("First entry is "+thisEntry);
        for(int j = (i+1); j<thisList.size(); j++){
            thatEntry = thisList.get(j);
            System.out.println("Second entry is "+thatEntry);
            if(thisEntry.equals(thatEntry)){
                thisList.remove(thatEntry);
            System.out.println("Entry removed: "+thatEntry);
            }
        }
            }
        return thisList;
    }

该方法成功删除了一些重复项。此方法运行之前的 ArrayList 如下所示(每个字母代表一个唯一的对象):

A B B C A B B A A B B B B C

在我运行该方法后,它显示为:

C A B B B C

我不明白为什么这种方法会重新排列结果并且仍然包含重复项,但我怀疑这是由于thisList内部 for 循环内发生了变化,但整体 for 循环仍然使用thisList. 那是对的吗?有什么办法解决这个问题?

标签: javalistfor-loopduplicates

解决方案


通过在迭代它时从列表中删除一个项目,你搞砸了你的逻辑。您不会像使用迭代器那样得到明显的显式失败,但是由于循环没有考虑到已删除的项目,您只是缺少项目。

一种更简单的方法是利用 JDK LinkedHashSet,它既保证每个值的单个实例,又保留插入顺序:

private static ist<IndividualEntry> cleanList(List<IndividualEntry> inputList) {
    return new ArrayList<>(new LinkedHashSet<>(inputList));
}

这当然假设您的IndividualEntry类正确实现了equals(Object)andhashCode()方法。


推荐阅读