我正在玩Java 8 lambdas来轻松过滤集合 . 但我没有找到一种简洁的方法来将结果检索为同一语句中的新列表 . 到目前为止,这是我最简洁的方法:
List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List<Long> targetLongList = new ArrayList<>();
sourceLongList.stream().filter(l -> l > 100).forEach(targetLongList::add);
网上的例子没有回答我的问题,因为他们停止而没有生成新的结果列表 . 必须有一个更简洁的方式 . 我原以为, Stream
类的方法为 toList()
, toSet()
,......
有没有办法可以直接由第三行分配变量 targetLongList
?
11 回答
如果您的流保持顺序,您正在做的事情可能是最简单的方式 - 否则您将不得不在
forEach
之前调用sequential() .[稍后编辑:调用sequential()的必要原因是,如果流是并行的,那么代码(
forEach(targetLongList::add)
)将会很有效 . 即使这样,它也不会达到预期的效果,因为forEach
明确是不确定的 - 即使在顺序流中也不能保证元素处理的顺序 . 您必须使用forEachOrdered
来确保正确的订购 . Stream API设计者的目的是在这种情况下使用收集器,如下所示 .另一种选择是
另一种方法是使用
Collectors.toCollection
:我喜欢使用一个util方法,它返回
ArrayList
的收集器,这就是我想要的 .我认为使用
Collectors.toCollection(ArrayList::new)
的解决方案对于这种常见操作来说有点太吵了 .例:
通过这个答案,我还想证明创建和使用自定义收集器是多么简单,这通常非常有用 .
如果您有一个基元数组,则可以使用Eclipse Collections中提供的基元集合 .
如果您无法从
List
更改sourceLongList:如果你想使用
LongStream
:注意:我是Eclipse Collections的贡献者 .
更有效的方法(避免创建源列表和过滤器自动取消装箱):
这是您可以用来将任何Stream转换为List的调用 .
如果你没有't mind using 3rd party libraries, AOL' s cyclops-react lib(披露我是贡献者)有所有JDK Collection类型的扩展名,包括List . ListX接口扩展了java.util.List并添加了大量有用的运算符,包括filter .
你可以简单地写 -
ListX也可以从现有List创建(通过ListX.fromIterable)
如果某人(像我一样)在寻找处理Objects而不是原始类型的方法,那么使用mapToObj()
打印:
这是代码AbacusUtil
披露:我是AbacusUtil的开发人员 .
如果你不使用
parallel()
,这将有效