Разница между итератором и сплитератором в Java8

Во время изучения я узнал, что Parallelism - главное преимущество Spliterator.

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
34
0
14 671
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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 должен делить свои элементы точно пополам, обеспечивая сбалансированное параллельное вычисление.

Процесс расщепления также называется «разбиением» или «декомпозицией».

как насчет размера или внутренних флагов? stackoverflow.com/a/51459530/1059372

Eugene 21.07.2018 21:46
Ответ принят как подходящий

Для меня имена в значительной степени говорят сами за себя. 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)

Другие вопросы по теме