Рубрики
Без рубрики

Apache Commons Collections SetUtils

Научитесь использовать API настроек библиотеки Apache Commons Collections.

Автор оригинала: baeldung.

1. Обзор

В этой статье мы рассмотрим SetUtils API библиотеки Apache Commons Collections. Проще говоря, эти утилиты могут быть использованы для выполнения определенных операций над структурами данных Set в Java.

2. Установка зависимостей

Для того чтобы мы могли использовать библиотеку Setuptools в нашем проекте, нам нужно добавить следующую зависимость к вашему проекту pom.xml файл:


    org.apache.commons
    commons-collections4
    4.1

В качестве альтернативы, если наш проект основан на Gradle, мы должны добавить зависимость в файл build.gradle нашего проекта. Кроме того, нам нужно добавить maven Central() в раздел репозиториев файла build.gradle :

compile 'org.apache.commons:commons-collections4:4.1'

3. Предикатное Множество

Метод predicatedSet() библиотеки SetUtils позволяет определить условия, которым должны соответствовать все элементы, которые должны быть вставлены в набор. Он принимает объект source Set и предикат.

Мы можем использовать это, чтобы легко проверить, что все элементы Set удовлетворяют определенному условию, что может быть удобно при разработке сторонней библиотеки/API.

Если проверка не выполняется для любого элемента, будет вызвано исключение IllegalArgumentException . Приведенный ниже фрагмент предотвращает добавление строк, которые не начинаются с ‘L’ в исходный набор или возвращаемый validatingSet :

Set validatingSet
  = SetUtils.predicatedSet(sourceSet, s -> s.startsWith("L"));

Библиотека также имеет predicatedSortedSet() и predicated NavigableSet() для работы с SortedSet и NavigableSet соответственно.

4. Объединение, Разность и Пересечение множества

В библиотеке есть методы, которые могут вычислять объединение, разность и пересечение элементов Set .

Метод difference() принимает два объекта Set и возвращает неизменяемый SetUtils. Установить вид объект. Возвращенные SetUtils. Set View содержит элементы, которые находятся в set a но не в set b :

Set a = new HashSet<>(Arrays.asList(1, 2, 5));
Set b = new HashSet<>(Arrays.asList(1, 2));
SetUtils.SetView result = SetUtils.difference(a, b);
 
assertTrue(result.size() == 1 && result.contains(5));

Обратите внимание, что пытается выполнить операции записи , такие как add() или addAll () , на возвращаемых SetUtils. setView вызовет исключение UnsupportedOperationException .

Чтобы изменить возвращаемый результат, нам нужно вызвать метод toSet() возвращаемого SetUtils. Set View для получения записываемого Set объекта:

Set mutableSet = result.toSet();

Метод union библиотеки SetUtils делает именно то, что звучит – он возвращает все элементы set a и b . Метод union также возвращает неизменяемый объект SetUtil.setView :

Set expected = new HashSet<>(Arrays.asList(1, 2, 5));
SetUtils.SetView union = SetUtils.union(a, b);
 
assertTrue(SetUtils.isEqualSet(expected, union));

Обратите внимание на метод isEqualSet () , используемый в операторе assert. Это удобный статический метод библиотеки SetUtils , который эффективно проверяет, равны ли два набора.

Чтобы получить пересечение множества, то есть элементов , которые присутствуют как в set a , так и в set b , мы будем использовать SetUtils. метод пересечения () . Этот метод также возвращает объект Set Util.Set View :

Set expected = new HashSet<>(Arrays.asList(1, 2));
SetUtils.SetView intersect = SetUtils.intersection(a, b);
 
assertTrue(SetUtils.isEqualSet(expected, intersect));

5. Преобразование Элементов Набора

Давайте рассмотрим еще один интересный метод – SetUtils. transformedSet() . Этот метод принимает объект Set и интерфейс Transformer . Опираясь на исходный набор, он использует метод transform() интерфейса Transformer для преобразования каждого элемента набора.

Логика преобразования определяется в методе transform() интерфейса Transformer , который применяется к каждому элементу, добавленному в набор. Приведенный ниже фрагмент кода умножает каждый элемент, добавленный в набор, на 2:

Set a = SetUtils.transformedSet(new HashSet<>(), e -> e * 2  );
a.add(2);
 
assertEquals(a.toArray()[0], 4);

Метод transformedSet() довольно удобен – его можно использовать даже для приведения элементов набора, скажем, из строки в целое число. Просто убедитесь, что тип вывода является подтипом ввода.

Допустим, мы работаем с SortedSet или NavigableSet вместо HashSet, мы можем использовать transformedSortedSet() или transformedNavigableSet() соответственно.

Обратите внимание, что новый экземпляр HashSet передается методу transformed Set () . В ситуациях, когда существующий, непустой Set передается методу, ранее существовавшие элементы не будут преобразованы.

Если мы хотим преобразовать уже существующие элементы (и те, которые были добавлены впоследствии), нам нужно использовать метод transformed Set() из org.apache.commons.collections4.set.TransformedSet :

Set source = new HashSet<>(Arrays.asList(1));
Set newSet = TransformedSet.transformedSet(source, e -> e * 2);
 
assertEquals(newSet.toArray()[0], 2);
assertEquals(source.toArray()[0], 2);

Обратите внимание, что элементы из исходного набора преобразуются, а результат копируется в возвращаемый новый набор.

6. Установите дизъюнкцию

Библиотека SetUtils предоставляет статический метод, который можно использовать для поиска дизъюнкций множеств. Дизъюнкция множества a и множества b – это все элементы, уникальные для множества a и множества b.

Давайте посмотрим, как использовать метод disjunction() библиотеки SetUtils :

Set a = new HashSet<>(Arrays.asList(1, 2, 5));
Set b = new HashSet<>(Arrays.asList(1, 2, 3));
SetUtils.SetView result = SetUtils.disjunction(a, b);
 
assertTrue(
  result.toSet().contains(5) && result.toSet().contains(3));

7. Другие методы в библиотеке SetUtils

В библиотеке SetUtils есть и другие методы, которые делают обработку заданных данных легким делом:

  • Мы можем использовать synchronized Set() или synchronizedSortedSet () , чтобы получить потокобезопасный Set . Однако, как указано в документах, мы должны вручную синхронизировать итератор возвращаемого набора, чтобы избежать недетерминированного поведения
  • Мы можем использовать SetUtils.unmodifiableSet () , чтобы получить набор только для чтения. Обратите внимание, что попытка добавить элементы в возвращаемый объект Set вызовет исключение UnsupportedOperationException
  • Существует также метод SetUtils.emptySet () , который возвращает типобезопасный неизменяемый пустой набор
  • Метод SetUtils.emptyIfNull() принимает объект nullable Set . Он возвращает пустой, только для чтения, S et , если поставляемый Set равен null; в противном случае он возвращает поставляемый Set
  • SetUtils.OrderedSet() вернет объект Set , который поддерживает порядок добавления элементов
  • SetUtils.hashCodeForSet() может генерировать хэш – код для набора-таким образом, что два набора одинаковых элементов будут иметь один и тот же хэш-код
  • СетУтилы.newIdentityHashSet() вернет HashSet , который использует == для сопоставления элемента вместо метода equals () . Пожалуйста, прочтите о его предостережениях здесь

8. Заключение

В этой статье мы исследовали все тонкости библиотеки SetUtils . Служебный класс предлагает статические методы, которые делают работу с заданной структурой данных легкой и увлекательной. Это также повышает производительность.

Как всегда, фрагменты кода доступны на GitHub . Официальный документ для API SetUtils можно найти здесь .