其他答案清楚地解释了Collection.stream 和Stream.of 之间的区别、何时使用其中一种、正在应用哪种设计模式等。@Holger 更进一步并展示了Stream.Builder 的示例用法,我认为它的使用率很低。
在这里,我想通过混合使用 Stream.of 和 Collection.stream 方法来补充其他答案。我希望这个例子足够清楚地表明即使Stream.of 和Collection.stream 是完全不同的方法,它们也可以一起使用来满足更复杂的需求。
假设您有N 列表,它们都包含相同类型的元素:
List<A> list1 = ...;
List<A> list2 = ...;
...
List<A> listN = ...;
并且您想创建一个包含所有列表元素的流。
您可以创建一个新的空列表并将所有列表的元素添加到这个新列表中:
int newListSize = list1.size() + list2.size() + ... + listN.size();
List<A> newList = new ArrayList<>(newListSize);
newList.addAll(list1);
newList.addAll(list2);
...
newList.addAll(listN);
然后,您可以在此列表中调用stream(),然后就完成了:
Stream<A> stream = newList.stream();
但是,您将创建一个中间的、毫无意义的列表,其唯一目的是流式传输原始 list1、list2、...、listN 列表的元素。
更好的方法是使用Stream.of:
Stream<A> stream = Stream.of(list1, list2, ..., listN)
.flatMap(Collection::stream);
这首先通过枚举每个列表来创建一个列表流,然后通过Stream.flatMap 操作将此列表流平面映射到所有列表元素的流中。因此,在平面映射原始流时会调用Collection.stream。