针对不同列表中的数据尝试filter
流:
它可以工作,但我在流的中间使用了一个for
循环。我找不到有关如何将for
循环转换为流的任何信息。
我可以.stream()
selction.getItems()
而不是.forEach()
并且有一个新的.stream()
DATA.accounts,但这是糟糕的代码,因为它必须在每个.forEach.
y=1;
DATA.accounts.stream()
.flatMap(estimate -> estimate.getElements().stream())
.filter( ele-> {
// different list;
for (Element element:selection.getItems()){
if (element.getId()==ele.getId()){
return true;
}
}
return false;
})
.forEach(element -> {
element.setDateSchedualed(selectedDate);
element.setOrder(y);
y++;
});
答案 0 :(得分:1)
我认为你真正需要的是:
list1.removeAll(list2);
虽然没有涉及流。
答案 1 :(得分:1)
将其他列表的ID放在Set selectedIds
中,然后根据ele-> selectedIds.contains(ele.getId())
进行过滤。
这将给你(摊销)线性时间复杂度。
由于你需要在selected
中检查流中每个项目的所有元素之间的存在,我不希望有任何简单的方法只使用流(因为你无法真正流式传输{{1}这个任务的集合。)
答案 2 :(得分:1)
您可以将filter
表达为
.filter(ele -> selection.getItems().stream()
.anyMatch(element -> element.getId()==ele.getId())
这个“必须重新预定”的事实不应该比原始代码为每个元素循环的事实更加困扰。在任何一种情况下,您都创建了O(n×m)
时间复杂度的操作。如果您可以肯定地预测其中一个列表总是非常小,那么这是可以接受的。
否则,通过将id值存储在具有快速(在最佳情况下为O(1)
)查找的结构中,无法准备此操作。即。
Set<IdType> id = selection.getItems().stream()
.map(element -> element.getId())
.collect(Collectors.toSet());
…
.filter(ele -> id.contains(ele.getId())
除此之外,当forEach
是局部变量时,y
方法明确增加y
变量是一种反模式,甚至不编译。如果y
是一个字段,它会使这个代码更糟糕。在这里,接受临时存储到List
:
Set<IdType> id = selection.getItems().stream().map(element -> element.getId());
List<ElementType> list = DATA.accounts.stream()
.flatMap(estimate -> estimate.getElements().stream())
.filter(ele -> id.contains(ele.getId())
.collect(Collectors.toList());
IntStream.range(0, list.size())
.forEach(ix -> {
ElementType element = list.get(ix);
element.setDateSchedualed(selectedDate);
element.setOrder(ix+1);
});
答案 3 :(得分:0)
我认为如果你想在线性时间内搜索id,那么使用for-each循环实际上并没有什么问题,因为例如你的项目列表是ArrayList
并且你使用了{{1}过滤的方法,它实际上也只是循环元素。您可以编写一般包含函数,如:
contains
并用它替换你的for-each循环:
public static <E1, E2> boolean contains(Collection<E1> collection, E2 e2, BiPredicate<E1, E2> predicate){
for (E1 e1 : collection){
if (predicate.test(e1, e2)){
return true;
}
}
return false;
}