java iterable
这是最近比较有趣的Stack Overflow问题之一:
为什么Iterable不提供stream()和parallelStream()方法?
最初,直接将Iterable转换为Stream似乎很直观,因为在90%的用例中,两者实际上或多或少是同一件事。
诚然,专家组非常注重使Stream API具有并行功能,但是每天使用Java的任何人都会立即注意到, Stream以其顺序形式最有用 。 而Iterable就是这样。 不保证并行化的顺序流。 因此,只有我们可以简单地编写以下内容,这才是直观的:
iterable.stream(); 实际上, Iterable子Iterable确实具有此类方法,例如
collection.stream(); Brian Goetz亲自回答了上述Stack Overflow问题 。 省略的原因是由于某些Iterables可能更喜欢返回IntStream而不是Stream 。 这似乎确实是做出设计决策的一个非常遥远的原因,但是与往常一样,今天的省略并不意味着永远的省略。 另一方面,如果他们今天引入了Iterable.stream() ,但事实证明这是一个错误,他们将无法再次将其删除。
好吧,Java中的原始类型很痛苦,它们首先对泛型造成了种种不良影响,现在对Stream也产生了各种不良影响,因为我们必须编写以下内容,才能将Iterable转换为Stream :
Stream s = StreamSupport.stream(iterable.spliterator(), false);Brian Goetz认为这很“容易”,但我不同意。 作为API使用者,由于以下原因,我在生产力方面遇到了很多摩擦:
- 必须记住此否则无用的
StreamSupport类型。 可以将这个方法很好地放到Stream接口中,因为我们已经有了Stream构造方法,例如Stream.of()。 - 在我认为与并行化无关的情况下,必须记住
Iterator和Spliterator之间的细微差别。 不过,极有可能Spliterators最终会变Spliterators流行,所以这个疑问是魔术8球需要解决的问题。 - 实际上,我必须重复以下信息:没有任何可通过布尔参数
false并行化的信息。
并行化在此新API中的作用确实很大,即使并行化仅覆盖所有功能集合操作的5%-10%。 尽管顺序处理不是JDK 8 API的主要设计目标,但确实对我们所有人都是主要的好处,与顺序处理相关的API周围的摩擦应尽可能小。
上面的方法应该刚刚被调用:
Stream s = Stream.stream(iterable);可以这样实现:
public static<T> Stream<T> stream(Iterable<T> i) {return StreamSupport.stream(i.spliterator(), false);
} 显然,便利性重载允许进行其他特殊化,例如并行化或通过Spliterator
但是,如果Iterable具有自己的stream()默认方法,那么即使没有显式支持Java 8的情况下,与Java 8集成的API数量也将大大增加。
以jOOQ为例。 jOOQ仍然支持Java 6,因此不可能直接依赖。 但是,jOOQ的ResultQuery类型是 Iterable 。 这使您可以直接在foreach循环中内联使用此类查询,就像编写PL / SQL一样:
PL / SQL
FOR book IN (SELECT * FROM books ORDER BY books.title
)
LOOP-- Do things with book
END LOOP;Java
for (BookRecord book : ctx.selectFrom(BOOKS).orderBy(BOOKS.TITLE)
) {// Do things with book
}现在想象一下Java 8中的同样情况:
ctx.selectFrom(BOOKS).orderBy(BOOKS.TITLE).stream().map / reduce / findAny, etc... 不幸的是,目前尚无法实现上述功能。 当然,您可以急切地将所有结果提取到jOOQ Result ,该Result扩展了List :
ctx.selectFrom(BOOKS).orderBy(BOOKS.TITLE).fetch().stream().map / reduce / findAny, etc...但是,这是另一种调用方法(每次),并且实际的流语义已被破坏,因为获取操作很忙。
高水平的抱怨
当然,这是一个高水平的抱怨,但是如果将来的Java版本(例如Java 9)将这种缺少的方法添加到Iterable API中,那将是非常不错的选择。 同样,所有用例中的99%都希望返回Stream类型,而不是IntStream类型。 并且,如果他们出于某种晦涩的原因而确实希望这样做(比起旧的旧版Java API的许多邪恶事物,晦涩得多, intStream()一下Calendar ),那么为什么他们不应该只声明一个intStream()方法呢? 毕竟,如果有人真的对int基本类型进行运算时,如果有人疯狂地编写Iterable<Integer> ,那么他们可能会接受一些解决方法。
翻译自: https://www.javacodegeeks.com/2014/12/really-too-bad-that-java-8-doesnt-have-iterable-stream.html
java iterable