我真的不知道如何表达这个问题的标题,因此我将举一个例子。

假设我要遍历元素列表,并根据某些条件将所述元素添加到新列表中。

在这里,我创建了一种方法,该方法基本上是要检查某项是否是第一个列表所独有的(第二个列表中不存在)。现在我知道,对于这个特定的愚蠢示例,您可以使用集合来解决此问题,但我只是想说明一个类似这样的情况会弹出的情况

public List<Item> newItems(List<Item> items, List<Item> otherItems) {
    List<Item> newItems = new ArrayList<>();

    for (Item i: items) {
        for (Item j: otherItems) {
            if (i.equals(j))
                //Missing code
        }
        newItems.add(i);
    }

    return newItems;
}

所以在这里,我只想将当前Item i添加到newItems中,如果它不等于otherItems中的单个项目。我的第一个冲动是将break;放在它表示//Missing Code的位置,但这只会跳出第一个循环,而不会阻止在i中添加newItems

我知道一个正确的解决方案,您将使用一个布尔变量来一致地检查if语句的真实性,然后在第二个循环结束时根据其真值将Item i添加到newItems中。它看起来像这样:
for (Item i: items) {
    boolean check = true;

    for (Item j: otherItems) {
        if (i.equals(j))
            check = false;
            break; //To avoid unnecessary iterations
    }

    if (check)
        newItems.add(i);
}

这似乎令人难以置信的庞大,但也很多余。有没有更有效,更优雅的方法?

最佳答案

如果我正确理解了您的问题,则需要创建一个列表,在其中列出items中收集的项目,但itemsotherItems中都存在的项目除外。如果是的话,您可以通过 List#removeAll() 来完成:

public List<Item> newItems(List<Item> items, List<Item> otherItems) {
    List<Item> res = new ArrayList<>(items);  // create a copy of items
    res.removeAll(otherItems);                // remove items presented in otherItems
    return res;
}

如果还有其他条件要排除项目,请使用流,过滤器和收集器,如下所示:
return items.stream()
            .filter(i -> !otherItems.contains(i))
            .filter( /* another condition */ )
            .collect(Collectors.toList());

09-11 20:54