在学习Parallelism
是Spliterator
的主要优势时,我才知道。
这可能是一个基本问题,但是有人可以向我解释Iterator
和Spliterator
之间的主要区别并举一些例子吗?
答案 0 :(得分:10)
对我来说,名字几乎是不言而喻的。 Spliterator
== 可拆分迭代器:它可以拆分某些源,也可以对其进行迭代。它具有与Iterator
相同的功能,但是它有可能分割成多个片段,这是trySplit
的目的。并行处理需要拆分。
Iterator
的大小始终未知,您只能通过hasNext/next
遍历元素; Spliterator
可以提供大小(从而在内部改善其他操作);可以是通过getExactSizeIfKnown
的精确值,也可以是estimateSize
的近似值。
另一方面,tryAdvance
是hasNext/next
来自Iterator
的内容,但这是一个单一方法,对于IMO而言更容易推论。与此相关的是forEachRemaining
,它在默认实现中委托给tryAdvance
,但不必总是这样。 (例如,参见ArrayList
)
通过它的内部属性,例如DISTINCT
或SORTED
等(您需要在实现自己的Spliterator
时正确提供),拆分器也是“更智能”的迭代器。这些标志在内部用于禁用不必要的操作,也称为优化,例如以下示例:
someStream().map(x -> y).count();
因为在流的情况下大小不会改变,所以map
可以完全跳过,因为我们所做的只是计数。
如果需要,您可以通过以下方式在迭代器周围创建一个拆分器:
Spliterators.spliteratorUnknownSize(yourIterator, properties)
答案 1 :(得分:7)
Iterator
是一系列可以迭代的元素的简单表示。
例如:
List<String> list = Arrays.asList("Apple", "Banana", "Orange");
Iterator<String> i = list.iterator();
i.next();
i.forEachRemaining(System.out::println);
#output
Banana
Orange
Spliterator
可用于将给定的元素集分成多个集合,以便我们可以在并行线程中对每个集合分别在不同线程中独立执行某种运算/计算。它被设计为Iterator的并行模拟。除集合外,分隔器覆盖的元素的来源可以是例如数组,IO通道或生成器函数。
Spliterator
界面中有2种主要方法。
-tryAdvance()和forEachRemaining()
使用tryAdvance(),我们可以一一遍历基础元素(就像Iterator.next()一样)。如果存在剩余元素,则此方法对其执行消费者操作,返回true;否则,返回true。否则返回false。
对于顺序批量遍历,我们可以使用forEachRemaining():
List<String> list = Arrays.asList("Apple", "Banana", "Orange");
Spliterator<String> s = list.spliterator();
s.tryAdvance(System.out::println);
System.out.println(" --- bulk traversal");
s.forEachRemaining(System.out::println);
System.out.println(" --- attempting tryAdvance again");
boolean b = s.tryAdvance(System.out::println);
System.out.println("Element exists: "+b);
输出:
Apple
--- bulk traversal
Banana
Orange
--- attempting tryAdvance again
Element exists: false
-分离器trySplit()
将此拆分器拆分为两个并返回新的拆分器:
List<String> list = Arrays.asList("Apple", "Banana", "Orange");
Spliterator<String> s = list.spliterator();
Spliterator<String> s1 = s.trySplit();
s.forEachRemaining(System.out::println);
System.out.println("-- traversing the other half of the spliterator --- ");
s1.forEachRemaining(System.out::println);
输出:
Banana
Orange
-- traversing the other half of the spliterator ---
Apple
理想的trySplit方法应将其元素精确地分成两半,以实现平衡的并行计算。
拆分过程也称为“分区”或“分解”。