首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >default Stream<E> stream() vs static<T> Stream<T> of(T t)

default Stream<E> stream() vs static<T> Stream<T> of(T t)
EN

Stack Overflow用户
提问于 2017-05-10 16:25:18
回答 4查看 365关注 0票数 4

为了支持Java8中的流,在Collection接口中添加了default Stream<E> stream()Stream类中的public static<T> Stream<T> of(T t)也支持类似的功能。static of()方法求解有什么不同的目的?

EN

回答 4

Stack Overflow用户

发布于 2017-05-10 18:33:27

可以在现有集合上调用Collection接口的stream()方法。作为一个接口方法,它可以被实际的集合实现覆盖,以返回适合特定集合类型的Stream

JRE的标准集合没有利用这个机会,因为默认实现的策略是委托给spliterator(),这也是一种可覆盖的方法,适合他们的需要。但是文档甚至提到了集合应该覆盖stream()的场景

spliterator()方法无法返回IMMUTABLECONCURRENT或后期绑定的拆分器时,应重写此方法。

相反,static工厂方法Stream.of(…)是为具有固定数量的元素而没有特定集合的情况而设计的。如果您想要的只是枚举元素上的单个Collection,则无需创建临时Stream

没有潜在不同类型的集合,就不需要可重写的行为,因此,static工厂方法就足够了。

请注意,即使您没有可枚举的固定数量的元素,当不需要可重用的集合时,也可以为创建单个流的任务提供优化的解决方案:

代码语言:javascript
运行
复制
Stream.Builder<MyType> builder=Stream.builder();
builder.add(A);
if(condition) builder.add(B);
builder.add(C);
builder.build()./* stream operations */
票数 6
EN

Stack Overflow用户

发布于 2017-05-10 16:48:50

据我所知,of只是一个动态创建流的实用方法,而不需要首先将元素包装在集合中。

通常会提供of等静态工厂方法来跳过数组的创建,因为有了var-args。例如,java-9不可变集合提供了这些方法的许多重载,例如:

代码语言:javascript
运行
复制
 Set.of()
 Set.of(E)
 Set.of(E e1, E e2)
 .... so on until 11
 Set.of(E... elem)

即使是这些方法的描述也是:

虽然这在API中引入了一些混乱,但它避免了由varargs调用引起的数组分配、初始化和垃圾收集开销。

由于Stream中只有两个方法:

代码语言:javascript
运行
复制
 Stream.of(T t)
 Streamm.of(T ... values)

我认为可以从var-args创建流的小实用程序方法。

但它们仍然提供了一种方法,可以创建具有单个元素的Stream (而不是只留下var-args方法),因此对于单个元素,这已经进行了优化。

票数 3
EN

Stack Overflow用户

发布于 2017-05-10 19:21:18

从jdk-8开始,接口可以添加静态方法/默认方法。您可以在this question中看到一些在接口上应用模式的示例。

对于First,它们都是调用StreamSupport.stream来创建流。

代码语言:javascript
运行
复制
// Collection.stream()
default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

// Stream.of(E)
public static<T> Stream<T> of(T t) {
    return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}

添加到集合接口的stream()是默认方法在接口中应用Template-Method Pattern的一个很好的例子。您可以看到流方法调用spliterator方法的源代码,该方法在集合接口中默认实现。

代码语言:javascript
运行
复制
default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

default Spliterator<E> spliterator() {
    return Spliterators.spliterator(this, 0);
}

Collection派生的类可以覆盖spliterator实现的不同算法,这些算法将使用最高性能算法。例如ArrayList中的spliterator

代码语言:javascript
运行
复制
public Spliterator<E> spliterator() {
    return new ArrayListSpliterator<>(this, 0, -1, 0);
}

最终,Stream.of()方法是通过静态方法在接口中应用Factory Method的一个很好的例子。它是一种工厂方法,用于从对象实例创建流。

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

https://stackoverflow.com/questions/43887175

复制
相关文章

相似问题

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