我有一个Item类,其中包含字段date,id和action。在我的情况下,我有旧项目列表和另一个列表,其中包括旧项目和新项目,所以我想过滤掉旧项目,所以我不会介意它们。例如,我迭代新项目,只使用那些不属于旧项目列表的项目。
使用for循环它看起来像这样,但我想以功能方式重写它
List<Item> filteredList = new ArrayList<>();
for (Item item : newList) {
for (Item oldItem : oldList) {
if (!item.getDate().equals(oldItem.getDate()) && !item.getId().equals(oldItem.getId()) && !item.getAction().equals(oldItem.getAction())) {
filteredList.add(item);
}
}
}
答案 0 :(得分:3)
首先,我建议在equals
课程中实施Item
方法,以避免这种复杂的情况(我不确定是否正确,BTW)。
其次,为了提高搜索效率,请将旧列表的元素放在HashSet
中,以便进行恒定时间查找。这将需要覆盖equals
类的hashCode
和Item
。
最后,代码将如下所示:
List<Item> filteredList =
newList.stream()
.filter(i -> !oldList.contains(i)) // oldList should be replaced with a HashSet
// for better performance
.collect(Collectors.toList());
使用HashSet
:
Set<Item> oldSet = new HashSet<>(oldList);
List<Item> filteredList =
newList.stream()
.filter(i -> !oldSet.contains(i))
.collect(Collectors.toList());
关于你的情况:
if (!item.getDate().equals(oldItem.getDate()) && !item.getId().equals(oldItem.getId()) && !item.getAction().equals(oldItem.getAction()))
看似错误,因为如果两个具有不同ID的项目具有相同的日期(或操作),则它们将无法通过测试。
我相信你打算写:
if (!item.getDate().equals(oldItem.getDate()) || !item.getId().equals(oldItem.getId()) || !item.getAction().equals(oldItem.getAction()))
这意味着如果两个项目中至少有一个属性不同,则认为两个项目彼此不同。
答案 1 :(得分:2)
首先,您应该在equals()
类中实现.hashCode()
方法(以及Item
),这样您就可以正确地比较项目,例如在使用时需要{ {1}} .contains()
method 。
然后,您可以使用List
方法测试.contains()
中是否存在当前项目,并根据该结果过滤项目。
使用Java 8,您的代码应如下所示:
oldList
注意:强>
请注意,此处使用List<Item> result = newList.stream()
.filter(line -> !oldList.contains(line))
.collect(Collectors.toList());
并不是必需的,因为您可以使用stream
方法实现此目的,例如.retainAll()
,这样您就可以过滤List
以更好的方式。
答案 2 :(得分:1)
此任务不需要流。只需使用List.removeAll
方法,它可以完全符合您的要求:
oldList.removeAll(newList);
这需要Item
类来实现equals()
方法,以便可以比较元素的相等性并将其删除。
如果您不想改变原始oldList
,可以创建一个新列表,然后从中删除元素:
List<Item> filteredList = new ArrayList<>(oldList);
filteredList.removeAll(newList);
另一种更实用的 ish 方法是使用Collection.removeIf
方法:
oldList.removeIf(item -> newList.contains(item));
或者只是:
oldList.removeIf(newList::contains);
这仍然需要Item
类来实现equals()
方法。但是,它也会效率低下,因为List.contains
需要遍历整个newList
以检查oldList
的每个项目是否属于它。更有效的方法是使用HashSet
:
Set<Item> newSet = new HashSet<>(newList);
然后,如上所述使用removeIf
:
oldList.removeIf(newSet::contains);
这种方法不仅要求Item
类实现equals()
方法,还需要hashCode
方法,该方法必须符合Object
类合同。平等。