Java 16 的 Stream.toList() 和 Stream.collect(Collectors.toList()) 的区别?
Differences of Java 16's Stream.toList() and Stream.collect(Collectors.toList())?
JDK 16 now includes a toList()
method directly on Stream
instances。在以前的 Java 版本中,您总是必须使用 collect
方法并提供一个 Collector
实例。
新方法明显减少了输入的字符。这两种方法是否可以互换,或者是否存在应该注意的细微差别?
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()
提供了一个不可变的 List
实现(类型 ImmutableCollections.ListN
无法添加或排序)类似于 List.of()
提供的实现与 Stream.collect(Collectors.toList())
.
提供的可变(可以更改和排序)ArrayList
相比
演示:
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");
}
}
输出:
[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)
请查看this article了解更多详情。
更新:
有趣的是,Stream.toList()
returns 一个包含 null
s 的列表成功了。
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);
}
}
输出:
[null, null]
另一方面,List.of(null, null)
抛出 NullPointerException
。
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Object> list = List.of(null, null);
}
}
输出:
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 SE 16 代码。
有用的资源:
- JDK错误#JDK-8180352
- Calling Java varargs method with single null argument?
这里有一个小小的table总结了Stream.collect(Collectors.toList())
、Stream.collect(Collectors.toUnmodifiableList())
和Stream.toList()
的区别:
collect(toList())
:保证不可修改性 - 否;允许空值 - 是
collect(toUnmodifiableList())
:保证不可修改性 - 是;允许空值 - 否
toList()
:保证不可修改性 - 是;允许空值 - 是
JDK 16 now includes a toList()
method directly on Stream
instances。在以前的 Java 版本中,您总是必须使用 collect
方法并提供一个 Collector
实例。
新方法明显减少了输入的字符。这两种方法是否可以互换,或者是否存在应该注意的细微差别?
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()
提供了一个不可变的 List
实现(类型 ImmutableCollections.ListN
无法添加或排序)类似于 List.of()
提供的实现与 Stream.collect(Collectors.toList())
.
ArrayList
相比
演示:
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");
}
}
输出:
[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)
请查看this article了解更多详情。
更新:
有趣的是,Stream.toList()
returns 一个包含 null
s 的列表成功了。
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);
}
}
输出:
[null, null]
另一方面,List.of(null, null)
抛出 NullPointerException
。
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Object> list = List.of(null, null);
}
}
输出:
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 SE 16 代码。
有用的资源:
- JDK错误#JDK-8180352
- Calling Java varargs method with single null argument?
这里有一个小小的table总结了Stream.collect(Collectors.toList())
、Stream.collect(Collectors.toUnmodifiableList())
和Stream.toList()
的区别:
collect(toList())
:保证不可修改性 - 否;允许空值 - 是collect(toUnmodifiableList())
:保证不可修改性 - 是;允许空值 - 否toList()
:保证不可修改性 - 是;允许空值 - 是