如何清除比较两个数组列表的重复项?

How to clear duplicates comparing two arraylists?

所以我有两个数组列表(这些只是作为示例)[Jeremy、Nick、Noah、Liam、Olivia] 和 [Elijah、Jeremy、Olivia、Sophia、Charlotte]。我将如何删除重复的“Jeremy”和“Olivia”,因为它们在第二个数组中。所以输出将是 firstArr: [Nick, Noah, Liam] 并且第二个 arraylist 将保持不变。这是我的方法,但不起作用。

public static ArrayList<String> removeDuplicates(ArrayList<String> firstArr, ArrayList<String> secArr) {
        for (int i = 0; i < firstArr.size(); ++i) {
            for (int p = 0; p < secArr.size(); ++p) {
                if (firstArr.get(i).equals(secArr.get(p))) {
                    firstArr.remove(i);
                    p = secArr.size();
                }
            }
        }
        return firstArr;
}

解决方案非常简单,我只需要在删除元素后执行 i--,因为所有内容都向左移动 1。

必须以这种方式进行提示,因为它是 class 的作业,我知道有更好的方法。

有很多方法可以做到这一点。但是,您需要记住的一件事是,如果您要修改它,您的循环不应该取决于集合大小;特别是如果您要删除元素。在遍历集合时修改集合的最佳方法是使用集合的 Iterator 对象并使用它来确定循环条件。例如,下面的代码等同于您要执行的操作:

public static void main(String[] args) {

    List<String> firstArr = new ArrayList<>();
    firstArr.add("Jeremy");
    firstArr.add("Nick");
    firstArr.add("Noah");
    firstArr.add("Liam");
    firstArr.add("Olivia");

    List<String> secondArr = new ArrayList<>();
    secondArr.add("Elijah");
    secondArr.add("Jeremy");
    secondArr.add("Olivia");
    secondArr.add("Sophia");
    secondArr.add("Charlotte");

    Iterator<String> firstIter = firstArr.iterator();
    while (firstIter.hasNext()) {
        String elem = firstIter.next();
        Iterator<String> secondIter = secondArr.iterator();
        while (secondIter.hasNext()) {
            String otherElem = secondIter.next(); // reacquire the iterator after each iteration. 
            if (elem.equals(otherElem)) {
                firstIter.remove(); // safely removes the current item using Iterator#remove()
            }
        }
    }
    System.out.println(firstArr);
}

输出符合预期[Nick, Noah, Liam]

如您所见,循环条件不依赖于集合的大小;只有在检查的条件下才有更多的元素要检查。如果没有,它就简单地退出循环(或者不允许循环完全开始)。这是修改集合时推荐的迭代方式。

我并不是说这是解决这个特定问题的最佳方法,但它是解决此问题的一种方法,并且如果您在遍历集合时需要修改集合,则必须知道这一点。实际上。使用 Java 流可以最好地解决这个特定问题:

firstArr = firstArr.stream().distinct().filter(Predicate.not(secondArr::contains)).collect.(Collectors.toList));

这个表达式替换了整个嵌套循环结构。基本上,您想收集第一个列表中不在第二个列表中的成员。谓词被否定的原因是因为过滤器函数将 return 如果不否定匹配元素。