实例。在以前的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()的性能会比Collectors.toList()好吗?,但关注的是行为,而不仅仅是性能。)
发布于 2021-01-30 16:04:13
一个不同之处是,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)
有关更多细节,请查看这篇文章。
更新:
有趣的是,Stream.toList()
成功地返回了一个包含null
的列表。
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 16代码的Java 16。
有用资源:
发布于 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是从赋值的左侧传播的。如果这两种类型不同,则在替换所有旧调用时可能会出现错误。
https://stackoverflow.com/questions/65969919
复制相似问题