Во время изучения я узнал, что Parallelism - главное преимущество Spliterator.
Это может быть базовый вопрос, но может ли кто-нибудь объяснить мне основные различия между Iterator и Spliterator и привести несколько примеров?





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 можно использовать для разделения заданного набора элементов на несколько наборов, чтобы мы могли выполнять какие-то операции / вычисления для каждого набора в разных потоках независимо, возможно, используя преимущества параллелизма. Он выполнен как параллельный аналог Итератора. Помимо коллекций, источником элементов, охватываемых Spliterator, может быть, например, массив, канал ввода-вывода или функция генератора.
В интерфейсе Spliterator есть 2 основных метода.
- tryAdvance () и forEachRemaining ()
С помощью tryAdvance () мы можем перемещаться по базовым элементам один за другим (точно так же, как Iterator.next ()). Если оставшийся элемент существует, этот метод выполняет над ним действие потребителя, возвращая истину; иначе возвращает 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 должен делить свои элементы точно пополам, обеспечивая сбалансированное параллельное вычисление.
Процесс расщепления также называется «разбиением» или «декомпозицией».
Для меня имена в значительной степени говорят сами за себя. Spliterator == Splittable Iterator: он может разбивать какой-то источник, а также может его повторять. Он имеет примерно ту же функциональность, что и Iterator, но с той дополнительной вещью, что он потенциально может разбить расколоть на несколько частей: это то, для чего предназначен trySplit. Разделение необходимо для параллельной обработки.
Iterator всегда имеет неизвестный размер: вы можете перемещаться по элементам только через hasNext/next; Spliterator может предоставить размер (таким образом, улучшая и другие операции изнутри); либо точный через getExactSizeIfKnown, либо приблизительный через estimateSize.
С другой стороны, tryAdvance - это то, что hasNext/next от Iterator, но это единственный метод, о котором гораздо проще рассуждать, ИМО. С этим связан forEachRemaining, который в реализации по умолчанию делегирует tryAdvance, но он не всегда должен быть таким (см., Например, ArrayList).
Spliterator также является «более умным» итератором благодаря своим внутренним свойствам, таким как DISTINCT или SORTED и т. д. (Которые вам необходимо правильно указать при реализации вашего собственного Spliterator). Эти флаги используются внутри для отключения ненужных операций; см., например, эту оптимизацию:
someStream().map(x -> y).count();
Поскольку размер не изменяется в случае потока, map можно полностью пропустить, поскольку все, что мы делаем, это подсчет.
Вы можете создать Spliterator вокруг Iterator, если вам нужно, с помощью:
Spliterators.spliteratorUnknownSize(yourIterator, properties)
как насчет размера или внутренних флагов? stackoverflow.com/a/51459530/1059372