Tag: spliterator

在Java 8的Spliterator中使用的奇怪循环

有人知道为什么java.util.Spliterator实现使用do-while而不是while循环,当循环体是空的时候? 例如, forEachRemaining的实现是: default void forEachRemaining(Consumer action) { do { } while (tryAdvance(action)); } 他们为什么要用 do { } while (tryAdvance(action)); 代替 while(tryAdvance(action)); ? 我不知道有什么好处吗?

Stream.spliterator对并行流的奇怪行为

我正在使用流分裂器直接用于我正在编写的库中的低级操作。 最近,当我使用流分裂器和交错tryAdvance/trySplit调用时,我发现了非常奇怪的行为。 这是一个简单的代码,演示了这个问题: import java.util.Arrays; import java.util.Spliterator; public class SpliteratorBug { public static void main(String[] args) { Integer[][] input = { { 1 }, { 2, 3 }, { 4, 5, 6 }, { 7, 8 }, { 9 } }; Spliterator spliterator = Arrays.stream(input).parallel() .flatMap(Arrays::stream).spliterator(); spliterator.trySplit(); spliterator.tryAdvance(s -> {}); spliterator.trySplit(); spliterator.forEachRemaining(System.out::println); } } 输出是 […]

Java 8 Spliterator(或类似的),如果只有一个值,则返回值

我是singleOrEmpty流操作员的singleOrEmpty粉丝。 它不在std lib中,但我发现它非常有用。 如果流只有一个值,则在Optional返回该值。 如果它没有值或多个值,则返回Optional.empty() 。 Optional value = someList.stream().{singleOrEmpty} [] -> Optional.empty() [1] -> Optional.of(1) [1, 1] -> Optional.empty() etc. 我之前问了一个关于它的问题,而@ThomasJungblut 想出了这个伟大的实现 : public static Optional singleOrEmpty(Stream stream) { return stream.limit(2) .map(Optional::ofNullable) .reduce(Optional.empty(), (a, b) -> a.isPresent() ^ b.isPresent() ? b : Optional.empty()); } 唯一的问题是,你必须把它放在通话的开头 singleOrEmpty(someList.stream().filter(…).map(…)) 而不是顺序结束 someList.stream().filter().map().singleOrEmpty() 这使得它比其他流机制更难阅读。 那么作为这个流处理工具的新手,有没有人知道如何在流转换序列结束时建立一个短路的singleOrEmpty机制呢?

不可分裂的分裂器

我试图了解Spliterator工作原理以及spliterator的设计方式。 我认识到trySplit()可能是Spliterator更重要的方法之一,但是当我看到一些第三方Spliterator实现时,有时我看到他们的分裂器无条件地为trySplit()返回null。 问题: 普通迭代器和Spliterator之间是否存在无条件返回null的Spliterator ? 似乎这样的分裂者击败了分裂的点。 当然,有一些合法的分裂器用例在trySplit()上有条件地返回null,但是有一个合理的spliterator用例无条件地返回null吗?

Java 8超级类流,父文件,组件父项,链表等

我想将以下for语句转换for Java 8流(即Stream<Class> )。 理想的解决方案很简单,我可以轻松地适应各种遍历链表的情况(例如File.getParentFile() , Component.getParent() )。 Class clazz; Object value; value = …; for (clazz = value.getClass(); clazz != null; clazz = clazz.getSuperclass()) … 我意识到创建流的几行代码不会比单个for语句简单。 但是,流使for循环的主体更简单,因此需要流。

了解Java 8和Java 9中的顺序流和并行流分裂器

关于劈开者的问题乍一看并不简单。 在流中, .parallel()更改流处理的行为。 但是我期望顺序和并行流创建的分裂器是相同的。 例如, 在顺序流中,通常不会调用.trySplit() ,而在并行流中,它是为了将拆分分裂器移交给另一个线程。 stream.parallel().spliterator()与stream.parallel().spliterator()之间的差异: 它们可能具有不同的特征: Stream.of(1L, 2L, 3L).limit(2); // ORDERED Stream.of(1L, 2L, 3L).limit(2).parallel(); // SUBSIZED, SIZED, ORDERED 这里讨论了另一个无意义的流分裂器特征策略(并行似乎更好地计算): 了解java 8和java 9中的深层分裂器特征 它们在使用.trySplit()分割方面可能有不同的行为: Stream.of(1L, 2L, 3L); // NON NULL Stream.of(1L, 2L, 3L).limit(2); // NULL Stream.of(1L, 2L, 3L).limit(2).parallel(); // NON NULL 为什么最后两个有不同的行为? 如果我愿意,为什么我不能拆分连续流? (例如,丢弃其中一个分割以进行快速处理可能很有用)。 将分裂器转换为流时的重大影响: spliterator = Stream.of(1L, 2L, 3L).limit(2).spliterator(); stream = StreamSupport.stream(spliterator, […]