Вступление:
Итераторы в Java используются для прохождения элементов данного источника. Spliterator в Java является одним из четырех доступных итераторов Java — Iterator, Enumeration, ListIterator и Spliterator . Это интерфейс, доступный в пакете java.util .
Spliterator был впервые представлен в Java 8 для поддержки параллельного программирования. Однако мы можем использовать его как для последовательной, так и для параллельной обработки элементов данных. Чтобы получить экземпляр Java Spliterator , мы будем использовать метод spliterator () :
1
2
|
List<Integer> list = Arrays.asList( 1 , 2 , 3 , 4 , 5 ); Spliterator splitr = list.spliterator(); |
Мы можем думать о Java Spliterator как:
1
|
Spliterator = Splitting + Iteration |
Характеристики сплитератора :
Интерфейс Spliterator определяет некоторые интегральные константы, представляющие его характеристики. Наш экземпляр может иметь одну или несколько из следующих восьми характеристик:
- SIZED — способен возвращать точное количество элементов в источнике, когда мы вызываем метод valuSize ()
- SUBSIZED — когда мы разделяем экземпляр с помощью trySplit () и получаем также SIZED SplitIterators
- ORDERED — перебор упорядоченной последовательности
- SORTED — перебирать отсортированную последовательность
- NONNULL — источник гарантирует, что значения не равны NULL
- DISTINCT — в нашей исходной последовательности нет дубликатов
- IMMUTABLE — если мы не можем структурно изменить источник элемента
- CONCURRENT — источник элемента может быть безопасно одновременно изменен
Мы можем использовать метод int Характеристики () для запроса характеристик нашего экземпляра Spliterator . Он возвращает значение OR для всех значений квалифицирующих признаков для нашего Spliterator . Для нашего определенного разделителя у нас будет:
1
|
int charactersticsORed = splitr.characteristics(); //16464 |
hasCharacteristics () :
Мы можем использовать логический метод hasCharacteristics (int признак), чтобы проверить, имеет ли наш экземпляр данную характеристику или нет:
1
2
3
|
boolean isSized = splitr.hasCharacteristics(Spliterator.SIZED); //true boolean isSorted = splitr.hasCharacteristics(Spliterator.SORTED); //false boolean isNonNull = splitr.hasCharacteristics(Spliterator.NONNULL); //false |
estimateSize ():
МетодtimateSize () возвращает приблизительное количество элементов, оставшихся для итерации. Он возвращает Long.MAX_VALUE, если значение бесконечно, неизвестно или слишком дорого для вычисления. Для SIZED Spliterator он возвращает значение, которое точно соответствует количеству элементов, которые будут встречаться при успешном обходе:
1
|
long estimatedSize = splitr.estimateSize(); // 5 |
getExactSizeIfKnown ():
Это просто вспомогательный метод, который возвращает оценкуSize (), если это SIZED Spliterator или возвращает -1 :
1
|
long size = splitr.getExactSizeIfKnown(); // 5 |
tryAdvance ():
Подпись метода tryAdvance () выглядит следующим образом:
1
|
default boolean tryAdvance(Consumer<? super T> action) |
Метод tryAdvance () в Spliterator объединяет операторы hasNext () и next (), присутствующие в базовом итераторе . Поэтому, если остающийся элемент существует, он выполняет с ним заданное действие, возвращая true; иначе возвращает ложь . Другими словами, он выполняет действие над следующим элементом в последовательности, а затем продвигает итератор.
1
|
while (splitr.tryAdvance((item) -> System.out.println(item))); |
Если у нас есть ORDERED Spliterator , действие выполняется над следующим элементом в порядке столкновения.
forEachRemaining ():
Метод forEachRemaining (Consumer <? SuperT> action) выполняет данное действие для каждого оставшегося элемента, последовательно в текущем потоке, пока все элементы не будут обработаны или действие не вызовет исключение:
1
|
splitr.forEachRemaining(item -> System.out.println(item)); |
Текущая реализация по умолчанию неоднократно вызывает tryAdvance (), пока не вернет false .
trySplit ():
Если разбиение возможно, метод trySplit () разделяет вызывающий Spliterator и возвращает ссылку на элементы покрытия Spliterator, которые не будут покрываться этим Spliterator по возвращении из этого метода. В противном случае возвращается ноль .
Таким образом, после успешного разделения оригинальный Spliterator будет выполнять итерацию по одной части последовательности, а возвращенный Spliterator — по другой ее части.
Кроме того, возвращаемый Spliterator охватывает строгий префикс элементов для начального ORDERED Spliterator (например, над списком ) :
01
02
03
04
05
06
07
08
09
10
|
// trySplit() method over ORDERED splitr Spliterator<Integer> splitrNew = splitr.trySplit(); // Elements in our splitrNew = {1, 2, 3} if (splitrNew != null ) { splitrNew.forEachRemaining((n) -> System.out.println(n)); } // Elements in our splitr - {4 , 5} splitr.forEachRemaining((n) -> System.out.println(n)); |
Если только наш оригинальный Spliterator не представляет бесконечную последовательность, повторные вызовы trySplit () должны в конечном итоге вернуть null .
getComparator () :
Если у нас есть Spliterator, отсортированный компаратором , он возвращает этот компаратор . Или же он возвращает ноль, если источник отсортирован в естественном порядке. Для источника, который не отсортирован , он выдаст исключение IllegalStateException .
Итак, для нашего примера мы имеем:
1
|
Comparator<Integer> comparator = splitr.getComparator(); //throws IllegalStateException |
Зачем использовать Spliterator?
Java Spliterator предлагает нам несколько преимуществ:
- Поддерживает параллельное программирование
- Мы можем использовать его как для последовательной, так и для параллельной обработки элементов данных.
- Метод tryAdvance () объединяет операции next () и hasNext () простого итератора и, таким образом, обеспечивает более высокую производительность.
Также важно понимать, что Spliterator отлично работает как для источников Collection, так и для потоков , но не с реализациями Map в качестве источника.
Вывод:
В этой статье мы познакомили вас с интерфейсом Spliterator в Java. Мы рассмотрели различные методы по умолчанию, доступные в этом интерфейсе, и способы их использования.
Оставьте первый комментарий.
Опубликовано на Java Code Geeks с разрешения Шубхры Шриваставы, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Использование Spliterator в Java Мнения, высказанные участниками Java Code Geeks, являются их собственными. |