从Java中的java.util.stream.Stream获取列表8

我正在玩Java 8 lambda来轻松过滤集合。 但是我没有找到一种简洁的方式在相同的语句中将结果作为新列表进行检索。 这是我迄今为止最简洁的方法:

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直接由第三行赋值?


如果您的数据流保持顺序,您正在做的事情可能是最简单的方法 - 否则您必须在forEach之前调用sequential()。

[稍后编辑:对sequential()的调用是必要的原因是,如果流是并行的,代码就会如此( forEach(targetLongList::add) )。 即使这样,也不会达到预期的效果,作为forEach是明确地不确定性,甚至在连续流元件处理的顺序不被保证。 您将不得不使用forEachOrdered来确保正确的排序。 Stream API设计人员的意图是,您将在这种情况下使用收集器,如下所示。]

另一种方法是

targetLongList = sourceLongList.stream()
    .filter(l -> l > 100)
    .collect(Collectors.toList());

另一种方法是使用Collectors.toCollection

targetLongList = 
    sourceLongList.stream().
    filter(l -> l > 100).
    collect(Collectors.toCollection(ArrayList::new));

我喜欢使用一种util方法,当我想要的时候它返回一个ArrayList的收集器。

我认为使用Collectors.toCollection(ArrayList::new)的解决方案对于这种常见操作有点过于嘈杂。

例:

ArrayList<Long> result = sourceLongList.stream()
    .filter(l -> l > 100)
    .collect(toArrayList());

public static <T> Collector<T, ?, ArrayList<T>> toArrayList() {
    return Collectors.toCollection(ArrayList::new);
}

有了这个答案,我也想演示创建和使用自定义收集器是多么简单,这通常非常有用。

链接地址: http://www.djcxy.com/p/58733.html

上一篇: Retrieving a List from a java.util.stream.Stream in Java 8

下一篇: OpenCV: refine contours that are similar to rectangles