首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java 16的Stream.toList()和Stream.collect(Collectors.toList())的区别?

Java 16的Stream.toList()和Stream.collect(Collectors.toList())的区别?
EN

Stack Overflow用户
提问于 2021-01-30 15:44:49
回答 2查看 20.2K关注 0票数 37

实例。在以前的Java版本中,您总是必须使用collect方法并提供一个Collector实例。

新的方法显然要输入的字符较少。这两种方法都是可以互换的,还是有细微的差别我们应该注意到?

代码语言:javascript
运行
复制
var newList = someCollection.stream()
    .map(x -> mapX(x))
    .filter(x -> filterX(x))
    .toList();

// vs.

var oldList = someCollection.stream()
    .map(x -> mapX(x))
    .filter(x -> filterX(x))
    .collect(Collectors.toList());

(这个问题类似于Stream.toList()的性能会比Collectors.toList()好吗?,但关注的是行为,而不仅仅是性能。)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-30 16:04:13

一个不同之处是,Stream.toList()提供的List实现是不可变的(不能添加或排序的ImmutableCollections.ListN类型),类似于List.of()提供的类型,与Stream.collect(Collectors.toList())提供的可变(可以更改和排序) ArrayList不同。

演示:

代码语言:javascript
运行
复制
import java.util.stream.Stream;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> list = Stream.of("Hello").toList();
        System.out.println(list);
        list.add("Hi");
    }
}

输出:

代码语言:javascript
运行
复制
[Hello]
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
    at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:147)
    at Main.main(Main.java:8)

有关更多细节,请查看这篇文章

更新:

有趣的是,Stream.toList()成功地返回了一个包含null的列表。

代码语言:javascript
运行
复制
import java.util.stream.Stream;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Object> list = Stream.of(null, null).toList();
        System.out.println(list);
    }
}

输出:

代码语言:javascript
运行
复制
[null, null]

另一方面,List.of(null, null)抛出NullPointerException

代码语言:javascript
运行
复制
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Object> list = List.of(null, null);
    }
}

输出:

代码语言:javascript
运行
复制
Exception in thread "main" java.lang.NullPointerException
    at java.base/java.util.Objects.requireNonNull(Objects.java:208)
    at java.base/java.util.ImmutableCollections$List12.<init>(ImmutableCollections.java:453)
    at java.base/java.util.List.of(List.java:827)
    at Main.main(Main.java:5)

注意:我使用openjdk-16-ea+34_osx-x64编译和执行Java 16代码的Java 16。

有用资源:

  1. JDK Bug#JDK-8180352
  2. 用单个空参数调用Java varargs方法?
票数 38
EN

Stack Overflow用户

发布于 2022-08-02 15:42:37

.collect(toList())toList()在创建的列表中元素的子类型兼容性方面表现为不同。

请看一看下列备选方案:

  • List<Number> old = Stream.of(0).collect(Collectors.toList());工作得很好,尽管我们将整数流收集到一个数字列表中。
  • List<Number> new = Stream.of(0).toList();是等效的Java版本,但它不编译(cannot convert from List<Integer> to List<Number>;至少在ecj中是Eclipse编译器)。

至少有两个解决方案可以修复编译错误:

  • 显式转换为所需类型的List<Number> fix1 = Stream.of(0).map(Number.class::cast).toList();
  • 在结果集合中允许子类型:List<? extends Number> fix2 = Stream.of(0).toList();

据我理解,根本原因如下:Java16 toList()的泛型类型T与流本身的泛型类型T相同。然而,Collectors.toList()的泛型类型T是从赋值的左侧传播的。如果这两种类型不同,则在替换所有旧调用时可能会出现错误。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65969919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档