**1. ** **Введение**
Эта статья является первой в серии о новых функциях, появившихся в версии 21 библиотеки Google Guava. Мы обсудим недавно добавленные классы и некоторые важные изменения по сравнению с предыдущими версиями Guava.
В частности, мы обсудим дополнения и изменения в пакете common.collect
.
Guava 21 представляет некоторые новые и полезные функции в пакете common.collect
; давайте кратко рассмотрим некоторые из этих новых утилит и то, как мы можем извлечь из них максимальную пользу.
2. Потоки
Мы все в восторге от последнего добавления java.util.stream.Stream
в Java 8. Итак, теперь Guava эффективно использует потоки и предоставляет то, что Oracle, возможно, упустила.
Streams
— это статический служебный класс с некоторыми необходимыми утилитами для обработки потоков Java 8.
2.1. Потоки.поток()
Класс Streams
предоставляет четыре способа создания потоков с использованием Iterable
, Iterator
, Optional
и Collection
.
Однако создание потока с использованием Collection
устарело, поскольку оно предоставляется Java 8 из коробки:
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Stream<Integer> streamFromCollection = Streams.stream(numbers);
Stream<Integer> streamFromIterator = Streams.stream(numbers.iterator());
Stream<Integer> streamFromIterable = Streams.stream((Iterable<Integer>) numbers);
Stream<Integer> streamFromOptional = Streams.stream(Optional.of(1));
Класс Streams
также предоставляет разновидности с OptionalDouble
, OptionalLong
и OptionalInt
. Эти методы возвращают поток, содержащий только этот элемент, иначе пустой поток:
LongStream streamFromOptionalLong = Streams.stream(OptionalLong.of(1));
IntStream streamFromOptionalInt = Streams.stream(OptionalInt.of(1));
DoubleStream streamFromOptionalDouble = Streams.stream(OptionalDouble.of(1.0));
2.2. Потоки.concat()
Класс Streams
предоставляет методы для объединения более чем одного однородного потока.
Stream<Integer> concatenatedStreams = Streams.concat(streamFromCollection, streamFromIterable,streamFromIterator);
Функциональность concat
представлена в нескольких вариантах — LongStream
, IntStream
и DoubleStream
.
2.3. Потоки.findLast()
Потоки
имеют служебный метод для поиска последнего элемента в потоке с помощью метода findLast()
.
Этот метод либо возвращает последний элемент, либо Optional.empty()
, если в потоке нет элементов:
List<Integer> integers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Optional<Integer> lastItem = Streams.findLast(integers.stream());
Метод findLast()
работает для LongStream
, IntStream
и DoubleStream
.
2.4. Потоки.mapWithIndex()
Используя метод mapWithIndex()
, каждый элемент потока несет информацию об их соответствующей позиции (индексе):
mapWithIndex( Stream.of("a", "b", "c"), (str, index) -> str + ":" + index)
Это вернет Stream.of("a:0", "b:1", "c:2")
.
То же самое может быть достигнуто с IntStream
, LongStream
и DoubleStream
с использованием перегруженного mapWithIndex()
.
2.5. Потоки.zip()
Чтобы сопоставить соответствующие элементы двух потоков с помощью некоторой функции, просто используйте метод zip для Streams:
Streams.zip(
Stream.of("candy", "chocolate", "bar"),
Stream.of("$1", "$2","$3"),
(arg1, arg2) -> arg1 + ":" + arg2
);
Это вернет Stream.of("конфеты: 1$", "шоколад: 2$", бар: 3$");
Результирующий поток будет такой же длины, как и более короткий из двух входных потоков; если один поток длиннее, его лишний элемент будет проигнорирован.
3. Компараторы
Класс Guava Ordering
устарел и находится на стадии удаления в более новых версиях. Большинство функций класса Ordering
уже включены в JDK 8.
Guava представляет компараторы
для предоставления дополнительных функций упорядочения
, которые еще не предоставляются стандартными библиотеками Java 8.
Давайте быстро взглянем на них.
3.1. Компараторы.isInOrder()
Этот метод возвращает true, если каждый элемент в Iterable больше или равен предыдущему, как указано Comparator
:
List<Integer> integers = Arrays.asList(1,2,3,4,4,6,7,8,9,10);
boolean isInAscendingOrder = Comparators.isInOrder(
integers, new AscedingOrderComparator());
3.2. Компараторы.isInStrictOrder()
Очень похож на метод isInOrder()
, но строго соблюдает условие, элемент не может быть равен предыдущему, он должен быть больше. Предыдущий код вернет false для этого метода.
3.3. Компараторы.лексикографический()
Этот API возвращает новый экземпляр Comparator
, который сортирует в лексикографическом (словарном) порядке, сравнивая соответствующие элементы попарно. Внутри он создает новый экземпляр LexicographicalOrdering<S>()
.
4. Больше коллекционеров
MoreCollectors
содержит несколько очень полезных коллекторов
, которых нет в Java 8 java.util.stream.Collectors
и которые не связаны с типом com.google.common
.
Давайте рассмотрим некоторые из них.
4.1. Дополнительные коллекторы.toOptional()
Здесь Collector
преобразует поток, содержащий ноль или один элемент, в необязательный
:
List<Integer> numbers = Arrays.asList(1);
Optional<Integer> number = numbers.stream()
.map(e -> e * 2)
.collect(MoreCollectors.toOptional());
Если поток содержит более одного элемента — сборщик выдаст исключение IllegalArgumentException.
4.2. БольшеКоллекторов.onlyElement()
С помощью этого API Collector
берет поток, содержащий только один элемент, и возвращает этот элемент; если поток содержит более одного элемента, он генерирует исключение IllegalArgumentException
или, если поток содержит нулевой элемент, он генерирует исключение NoSuchElementException
.
5. Интернеры.InternerBuilder
Это внутренний класс построителя для уже существующей библиотеки Interners
в Guava. Он предоставляет удобный метод для определения уровня параллелизма и типа (слабый или сильный) Interner
, который вы предпочитаете:
Interners interners = Interners.newBuilder()
.concurrencyLevel(2)
.weak()
.build();
6. Заключение
В этой быстрой статье мы рассмотрели недавно добавленные функции в пакете common.collect
для Guava 21.
Код этой статьи , как всегда, можно найти на Github .