Перейти к основному содержимому

Новый поток, компаратор и коллектор в Guava 21

· 4 мин. чтения

Задача: Сумма двух чисел

Напишите функцию twoSum. Которая получает массив целых чисел nums и целую сумму target, а возвращает индексы двух чисел, сумма которых равна target. Любой набор входных данных имеет ровно одно решение, и вы не можете использовать один и тот же элемент дважды. Ответ можно возвращать в любом порядке...

ANDROMEDA

**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 .