Java如何将Stream收集到List中

后端 潘老师 4个月前 (10-30) 87 ℃ (0) 扫码查看

通过不同的方式,我们可以从 Stream 中收集元素并将其存储到 List 中。我们将通过示例比较这几种实现方式,以便我们在不同情形下选择最佳的方法。

在 Java 中,主要有三种方法可以将 Stream 对象收集到 List 对象中。让我们来比较一下这三种方法:

1. 3种方法

1.1 JDK16使用Stream.toList()

  • 在 Java 16 中添加了 toList() 方法。这是一个默认方法,它将Stream 元素收集存储到一个不可修改的 List 中。
  • 返回的列表是 Collections.unmodifiableList(new ArrayList<>(Arrays.asList(stream.toArray()))) 的实现,其中 stream 表示底层 Stream 的元素。
  • 如果Stream是有序的,那么收集好的List中的元素顺序将与Stream流中的顺序保持一致。
  • 由于返回的 List 是不可修改的,对任何更改List方法的调用都将引发 UnsupportedOperationException。
  • 这是一个终止操作。
Stream<String> tokenStream = Stream.of("A", "B", "C", "D");
List<String> tokenList = tokenStream.toList();

1.2 JDK10使用Stream.collect(Collectors.toUnmodifiableList())

  • 在 Java 10 中添加了这个方法。这是一个终止操作,它将 Stream 元素收集到一个不可修改的 List 中。
  • 返回的列表是 Collections.unmodifiableList() 的实例,它使用 JDK 内部 API 来填充流项目,这些 API 能够无需使用反射即可访问 JDK 类的私有方法。在这种情况下,不可修改的列表是 SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(list.toArray()) 的实现,其中列表是一个中间的和可变的流元素List。
  • 该列表不允许空值,如果流中有空值,整个操作将引发 NullPointerException。
  • 如果Stream是有序的,那么收集好的List中的元素顺序将与Stream流中的顺序保持一致。
Stream<String> tokenStream = Stream.of("A", "B", "C", "D");
List<String> tokenList = tokenStream.collect(Collectors.toUnmodifiableList());

1.3. JDK8使用Stream.collect(Collectors.toList())

  • 这个方法在Java 8中与原始Stream API一起被添加进来。
  • 这是一个终止操作,它把Stream的项收集到一个可变的List中。
  • 返回的列表是ArrayList类的一个实例。
  • 类似其他JDK版本,如果stream中元素师有序的,那么可变List中的项的顺序将与流中的顺序保持一致。
Stream<String> tokenStream = Stream.of("A", "B", "C", "D");
List<String> tokenList = tokenStream.collect(Collectors.toList());

2. 将流收集到LinkedList中

使用 Collectors.toCollection(LinkedList::new) API 与 Stream.collect() API 一起将流元素收集到LinkedList中。

Stream<String> tokenStream = Arrays.asList("A", "B", "C", "D").stream();
List<String> tokenList = tokenStream
                .collect(Collectors.toCollection(LinkedList::new));

3.过滤流并收集项目到List

有时,我们需要从流中只找到特定的项,然后将这些项添加到列表中。在这里,我们可以使用 Stream.filter() 方法传递一个Predicate,该谓词将只返回符合给定先决条件的项。

在给定的示例中,我们正在过滤所有工资低于 400 的员工。然后,我们将这些员工收集到一个列表中。

Stream<Employee> employeeStream = Stream.of(
          new Employee(1, "A", 100),
          new Employee(2, "B", 200),
          new Employee(3, "C", 300),
          new Employee(4, "D", 400),
          new Employee(5, "E", 500),
          new Employee(6, "F", 600));
List<Employee> employeeList = employeeStream
        .filter(e -> e.getSalary() < 400)
        .collect(Collectors.toList());

4. 从无限流中收集项目到List

要将无限流转换为列表,我们必须将流限制为有限数量的元素(即使用limit()方法进行截断)。给定示例适用于原始数据流的 情况。

IntStream infiniteNumberStream = IntStream.iterate(1, i -> i+1);
List<Integer> integerlist = infiniteNumberStream.limit(10)
        .boxed()
        .collect(Collectors.toList());

5. 结论

在本教程中,我们学习了与流一起工作的不同方法,并将流项收集到List中。

作为一般准则,我们可以使用 Stream.toList() 用于收集到不可修改的List,并使用 Stream.collect(Collectors.toList()) 用于收集到可修改的List列表。

要收集到任何其他类型的 List 中,我们必须使用l类似 Stream.collect(Collectors.toCollection(LinkedList::new)) 的方法。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/10493.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】