В Java Spliterator(разделяемый итератор) — это интерфейс в пакете 'java.util', который используется для разбиения и параллельного обхода элементов коллекции. В отличие от традиционных итераторов, Spliterator разработан с учетом параллелизма и в основном помогает в параллельной обработке, когда коллекция или поток имеют большое количество элементов.
В нормальных условиях Spliterator будет вести себя точно так же, как Iterator.
Spliterator<T> spliterator = list.spliterator();
1. Особенности Сплитератора
Ниже приведен список функций, предоставляемых Spliterator на Java.
- Spliterator был представлен в Java 8.
- Обеспечивает поддержку параллельной обработки потока элементов для любой коллекции.
- Он предоставляет метод tryAdvance() для итерации элементов по отдельности в разных потоках. Он помогает в параллельной обработке.
- Для последовательного перебора элементов в одном потоке используйте метод forEachRemaining().
- Метод trySplit() используется для разделения сплитератора, если это возможно.
- Он помогает объединить операции hasNext() и next() в один метод.
2. Методы разделения
Название метода | Описание |
---|---|
характеристики() | Возвращает список характеристик spliterator. Это может быть любой из ORDERED, DISTINCT, SORTED, SIZED, NONULL, IMMUTABLE, CONCURRENT и SUBSIZED. |
оценкаРазмер() | Возвращает оценку количества элементов, которые будут обнаружены при обходе forEachRemaining(), или возвращает Long.MAX_VALUE, если число бесконечно, неизвестно или слишком затратно для вычисления. |
forEachRemaining(Действие потребителя) | Выполняет заданное действие для каждого оставшегося элемента последовательно в текущем потоке, пока все элементы не будут обработаны или пока действие не выдаст исключение. |
получитьКомпаратор() | Если источник разделителя отсортирован компаратором, возвращает этот компаратор. |
получитьТочныйРазмерЕслиИзвестно() | Возвращает estimateSize(), если этот Spliterator имеет размер SIZE, в противном случае -1. |
tryAdvance(Действие потребителя) | Если оставшийся элемент существует, то выполнить указанное действие над ним, возвращая true; в противном случае вернуть false. |
попробуйтеРазделить() | Если spliterator может быть разделен, возвращает Spliterator, покрывающий элементы, которые после возврата из этого метода не будут покрыты этим Spliterator. |
3. Сплиттератор с потоком
Каркас сбора данных Java предоставляет методы stream() и parallelStream() по умолчанию, которые внутренне используют Spliterator через вызов spliterator(). Это помогает обрабатывать сбор данных параллельно.
default Stream<E> stream() {return StreamSupport.stream(spliterator, false);}default Stream<E> parallelStream() {return StreamSupport.stream(spliterator, true);}
4. Пример Java Spliterator
4.1. Характеристики сплиттератора() Пример
Пример Java для проверки характеристик Spliterator, полученных для ArrayList.
ArrayList<String> list = new ArrayList<>();Spliterator<String> spliterator = list.spliterator();int expected = Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;System.out.println(spliterator.characteristics() == expected); //trueif(spliterator.hasCharacteristics(Spliterator.ORDERED)) {System.out.println("ORDERED");}if(spliterator.hasCharacteristics(Spliterator.DISTINCT)) {System.out.println("DISTINCT");}if(spliterator.hasCharacteristics(Spliterator.SORTED)) {System.out.println("SORTED");}if(spliterator.hasCharacteristics(Spliterator.SIZED)) {System.out.println("SIZED");}if(spliterator.hasCharacteristics(Spliterator.CONCURRENT)) {System.out.println("CONCURRENT");}if(spliterator.hasCharacteristics(Spliterator.IMMUTABLE)) {System.out.println("IMMUTABLE");}if(spliterator.hasCharacteristics(Spliterator.NONNULL)) {System.out.println("NONNULL");}if(spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {System.out.println("SUBSIZED");}
Вывод программы.
trueORDEREDSIZEDSUBSIZED
4.2. Разделитель estimateSize() и getExactSizeIfKnown()
Пример Java для получения размера резервной коллекции, т.е. количества элементов для итерации с помощью spliterator.
ArrayList<String> list = new ArrayList<>();list.add("A");list.add("B");list.add("C");list.add("D");Spliterator<String> spliterator = list.spliterator();System.out.println(spliterator.estimateSize());System.out.println(spliterator.getExactSizeIfKnown());
Вывод программы.
44
4.3. Разделитель getComparator()
Пример Java для поиска компаратора, используемого spliterator.
SortedSet<String> set = new TreeSet<>( Collections.reverseOrder() );set.add("A");set.add("D");set.add("C");set.add("B");System.out.println(set);System.out.println(set.spliterator().getComparator());
Вывод программы.
[D, C, B, A]java.util.Collections$ReverseComparator@7852e922
4.4 Пример использования функции сплиттератора trySplit()
Пример Java для разделения элементов на две группы и независимой итерации.
ArrayList<String> list = new ArrayList<>();list.add("A");list.add("B");list.add("C");list.add("D");list.add("E");list.add("F");Spliterator<String> spliterator1 = list.spliterator();Spliterator<String> spliterator2 = spliterator1.trySplit();spliterator1.forEachRemaining(System.out::println);System.out.println("========");spliterator2.forEachRemaining(System.out::println);
Вывод программы.
DEF========ABC
4.5 Пример использования Spliterator forEachRemaining()
Пример Java для выполнения операций hasNext() и next() в одном операторе с использованием метода forEachRemaining().
ArrayList<String> list = new ArrayList<>();list.add("A");list.add("B");list.add("C");list.add("D");Spliterator<String> spliterator = list.spliterator();spliterator.forEachRemaining(System.out::println);
Вывод программы.
ABCD
5. Заключение
В этом уроке мы изучили интерфейс Java Spliterator. Мы изучили методы Spliterator и простые примеры для итерации по элементам коллекций и потокам, помимо других полезных методов в Spliterator.
Пишите мне свои вопросы в разделе комментариев.
Ссылки: Интерфейс Spliterator Java Docs