我可以把下面的代码减少到一行或两行吗?
DTO dto;
List<DTO> dtos;
List<Integer> list1 = dtos.stream().map(DTO::getFirstId).distinct().collect(Collectors.toList());
List<Integer> list2 = dtos.stream().map(DTO::getSecondId).distinct().collect(Collectors.toList());
List<Integer> reducedId = list1.stream().filter(list2::contains).collect(Collectors.toList());
5条答案
按热度按时间sq1bmfud1#
使用单个Java8流在这里不是一个好的选择,相反,您应该首先创建一个Set,以便可以执行有效的包含测试。
li9yvcax2#
您可以强制将其合并到一个流操作中,但是性能会比您现在所拥有的(即具有二次时间复杂度的操作)还要差。
更好的方法是:
通过将第二个ID收集到
Set
而不是List
中,您无需在第一个流操作中使用distinct()
,并且避免了在调用contains
时对第二个流操作中的每个元素应用线性搜索。一般可以考虑使用
Set
来记忆唯一ID,当使用Set
作为结果类型时,也可以避免第二个流操作的distinct()
:如果您怀疑存在大量重复的ID,并希望在检查其他
Set
之前保留对重复项进行排序的行为,则可以用途:请注意,如果您喜欢又长又难读的“一行程序”,则可以在所有变体中内联
set
变量。djmepvbi3#
如果你愿意使用第三方库,你可以选择使用Eclipse Collections。如果你想使用
Stream
,下面的代码应该可以使用Collectors2
。Eclipse集合也有它唯一的
LazyIterable
类型可以用来代替Stream
。最后,如果你有大量的id,你可能想使用原语集来避免装箱
Integer
对象。你可以再次使用Stream
和Collectors2
,如下所示:也可以按如下方式使用
LazyIterable
:注意:我是Eclipse Collections的提交者。
b5buobof4#
使用StreamEx时:
或通过abacus-common
eoxn13cs5#
我觉得你可以做一些
没有在我当地测试,但在我看来是合理的:)