在Java中从java.util.stream.Stream中检索列表

我正在玩Java 8 lambda来轻松过滤集合。 但是,我没有find一个简洁的方法来检索结果作为一个新的列表在同一语句。 这是我迄今为止最简洁的方法:

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() ,…

有没有一种方法,variablestargetLongList可以直接由第三行分配?

你正在做的事情可能是最简单的方法,只要你的stream保持顺序,否则你必须在forEach之前调用sequential()。

[稍后编辑:对sequential()的调用是必要的原因是,代码(如forEach(targetLongList::add) )如果stream是并行的将是活泼的。 即使如此,它也不会达到预期的效果,因为每个明确的不确定性 – 即使在顺序stream中,元素处理的顺序也不能保证。 你将不得不使用forEachOrdered来确保正确的顺序。 Stream APIdevise者的意图是你将在这种情况下使用收集器,如下所示。]

另一种方法是

 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)的解决scheme对于这样的常见操作来说有点过于嘈杂。

例:

 ArrayList<Long> result = sourceLongList.stream() .filter(l -> l > 100) .collect(toArrayList()); public static <T> Collector<T, ?, ArrayList<T>> toArrayList() { return Collectors.toCollection(ArrayList::new); } 

有了这个答案,我也想演示如何简单的创build和使用自定义collections家,这是非常有用的一般。

一个更有效的方法(避免创build源列表和filter的自动拆箱):

 List<Long> targetLongList = LongStream.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L) .filter(l -> l > 100) .boxed() .collect(Collectors.toList()); 

如果您有一个基元数组,您可以使用Eclipse集合中可用的基元集合。

 LongList sourceLongList = LongLists.mutable.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L); LongList targetLongList = sourceLongList.select(l -> l > 100); 

如果你不能从List更改sourceLongList:

 List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L); List<Long> targetLongList = ListAdapter.adapt(sourceLongList).select(l -> l > 100, new ArrayList<>()); 

如果你想使用LongStream

 long[] sourceLongs = new long[]{1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L}; LongList targetList = LongStream.of(sourceLongs) .filter(l -> l > 100) .collect(LongArrayList::new, LongArrayList::add, LongArrayList::addAll); 

注意:我是Eclipse Collections的贡献者。

如果您不介意使用第三方库,AOL的独眼巨人反应 lib(披露我是贡献者)有所有JDK集合types的扩展,包括列表 。 ListX接口扩展java.util.List并添加了大量有用的运算符,包括filter。

你可以简单地写 –

 ListX<Long> sourceLongList = ListX.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L); ListX<Long> targetLongList = sourceLongList.filter(l -> l > 100); 

ListX也可以从现有的列表(通过ListX.fromIterable)

 collect(Collectors.toList()); 

这是您可以用来将任何stream转换为列表的调用。

如果有人(像我)在寻找方式处理对象而不是原始types,然后使用mapToObj()

 String ss = "An alternative way is to insert the following VM option before " + "the -vmargs option in the Eclipse shortcut properties(edit the " + "field Target inside the Shortcut tab):"; List<Character> ll = ss .chars() .mapToObj(c -> new Character((char) c)) .collect(Collectors.toList()); System.out.println("List type: " + ll.getClass()); System.out.println("Elem type: " + ll.get(0).getClass()); ll.stream().limit(50).forEach(System.out::print); 

打印:

 List type: class java.util.ArrayList Elem type: class java.lang.Character An alternative way is to insert the following VM o 

这里是AbacusUtil的代码

 LongStream.of(1, 10, 50, 80, 100, 120, 133, 333).filter(e -> e > 100).toList(); 

披露:我是AbacusUtil的开发者。

 String joined = Stream.of(isRead?"read":"", isFlagged?"flagged":"", isActionRequired?"action":"", isHide?"hide":"") .filter(s -> s != null && !s.isEmpty()) .collect(Collectors.joining(",")); 

如果你不使用parallel()这将工作

 List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L); List<Long> targetLongList = new ArrayList<Long>(); sourceLongList.stream().peek(i->targetLongList.add(i)).collect(Collectors.toList());