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

Руководство по коллекциям Apache Commons CollectionUtils

Узнайте, как выполнять общие операции с коллекциями с помощью CollectionUtils.

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

1. Обзор

Проще говоря, Apache CollectionUtils предоставляет служебные методы для общих операций, которые охватывают широкий спектр вариантов использования и помогают избежать написания шаблонного кода. Библиотека предназначена для более старых выпусков JVM, поскольку в настоящее время аналогичная функциональность предоставляется API Java 8 Stream .

2. Зависимости Maven

Нам нужно добавить следующую зависимость, чтобы начать работу с CollectionUtils:


    org.apache.commons
    commons-collections4
    4.1

Последнюю версию библиотеки можно найти здесь .

3. Настройка

Давайте добавим классы Customer и Address:

public class Customer {
    private Integer id;
    private String name;
    private Address address;

    // standard getters and setters
}

public class Address {
    private String locality;
    private String city;
   
    // standard getters and setters
}

Мы также будем держать под рукой следующие экземпляры Customer и List , готовые протестировать нашу реализацию:

Customer customer1 = new Customer(1, "Daniel", "locality1", "city1");
Customer customer2 = new Customer(2, "Fredrik", "locality2", "city2");
Customer customer3 = new Customer(3, "Kyle", "locality3", "city3");
Customer customer4 = new Customer(4, "Bob", "locality4", "city4");
Customer customer5 = new Customer(5, "Cat", "locality5", "city5");
Customer customer6 = new Customer(6, "John", "locality6", "city6");

List list1 = Arrays.asList(customer1, customer2, customer3);
List list2 = Arrays.asList(customer4, customer5, customer6);
List list3 = Arrays.asList(customer1, customer2);

List linkedList1 = new LinkedList<>(list1);

4. Коллекционные материалы

Давайте рассмотрим некоторые из наиболее часто используемых методов в Apache Commons CollectionUtils класс.

4.1. Добавление Только Ненулевых Элементов

Мы можем использовать Collectionutils addIgnoreNull метод добавления только ненулевых элементов в предоставленную коллекцию.

Первым аргументом этого метода является коллекция, в которую мы хотим добавить элемент, а вторым аргументом-элемент, который мы хотим добавить:

@Test
public void givenList_whenAddIgnoreNull_thenNoNullAdded() {
    CollectionUtils.addIgnoreNull(list1, null);
 
    assertFalse(list1.contains(null));
}

Обратите внимание, что null не был добавлен в список.

4.2. Сопоставление Списков

Мы можем использовать метод collate для сортировки двух уже отсортированных списков. Этот метод принимает оба списка, которые мы хотим объединить, в качестве аргументов и возвращает один отсортированный список:

@Test
public void givenTwoSortedLists_whenCollated_thenSorted() {
    List sortedList = CollectionUtils.collate(list1, list2);

    assertEquals(6, sortedList.size()); 
    assertTrue(sortedList.get(0).getName().equals("Bob"));
    assertTrue(sortedList.get(2).getName().equals("Daniel"));
}

4.3. Преобразование Объектов

Мы можем использовать метод transform для преобразования объектов класса A в различные объекты класса B. Этот метод принимает в качестве аргументов список объектов класса A и a transformer .

Результатом этой операции является список объектов класса B:

@Test
public void givenListOfCustomers_whenTransformed_thenListOfAddress() {
    Collection
addressCol = CollectionUtils.collect(list1, new Transformer() { public Address transform(Customer customer) { return customer.getAddress(); } }); List
addressList = new ArrayList<>(addressCol); assertTrue(addressList.size() == 3); assertTrue(addressList.get(0).getLocality().equals("locality1")); }

4.4. Фильтрация объектов

С помощью filter мы можем удалить из списка объекты, которые не удовлетворяют заданному условию . Метод принимает список в качестве первого аргумента и Предикат в качестве второго аргумента.

Метод filter Inverse делает обратное. Он удаляет объекты из списка, когда предикат возвращает true.

Оба фильтр и обратный фильтр вернуть истинный если входной список был изменен, т. е. Если хотя бы один объект был отфильтрован из списка:

@Test
public void givenCustomerList_WhenFiltered_thenCorrectSize() {
    
    boolean isModified = CollectionUtils.filter(linkedList1, 
      new Predicate() {
        public boolean evaluate(Customer customer) {
            return Arrays.asList("Daniel","Kyle").contains(customer.getName());
        }
    });
     
    assertTrue(linkedList1.size() == 2);
}

Мы можем использовать select и select Rejected , если хотим, чтобы возвращался результирующий список, а не логический флаг.

4.5. Проверка на наличие непустых

Метод isNotEmpty очень удобен, когда мы хотим проверить, есть ли в списке хотя бы один элемент. Другой способ проверить то же самое:

boolean isNotEmpty = (list != null && list.size() > 0);

Хотя приведенная выше строка кода делает то же самое, CollectionUtils.isNotEmpty делает наш код чище:

@Test
public void givenNonEmptyList_whenCheckedIsNotEmpty_thenTrue() {
    assertTrue(CollectionUtils.isNotEmpty(list1));
}

пусто делает обратное. Он проверяет, является ли данный список нулевым или в нем есть нулевые элементы:

List emptyList = new ArrayList<>();
List nullList = null;
 
assertTrue(CollectionUtils.isEmpty(nullList));
assertTrue(CollectionUtils.isEmpty(emptyList));

4.6. Проверка Включения

Мы можем использовать isSubCollection , чтобы проверить, содержится ли коллекция в другой коллекции. isSubCollection принимает две коллекции в качестве аргументов и возвращает true , если первая коллекция является вложенной коллекцией второй коллекции:

@Test
public void givenCustomerListAndASubcollection_whenChecked_thenTrue() {
    assertTrue(CollectionUtils.isSubCollection(list3, list1));
}

Коллекция является субколлекцией другой коллекции, если количество раз, когда объект встречается в первой коллекции, меньше или равно количеству раз, когда он встречается во второй коллекции.

4.7. Пересечение коллекций

Мы можем использовать метод CollectionUtils.intersection для получения пересечения двух коллекций. Этот метод принимает две коллекции и возвращает коллекцию элементов, которые являются общими в обеих входных коллекциях:

@Test
public void givenTwoLists_whenIntersected_thenCheckSize() {
    Collection intersection = CollectionUtils.intersection(list1, list3);
    assertTrue(intersection.size() == 2);
}

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

4.8. Вычитание Коллекций

CollectionUtils.subtract принимает две коллекции в качестве входных данных и возвращает коллекцию, содержащую элементы, которые находятся в первой коллекции, но не во второй коллекции:

@Test
public void givenTwoLists_whenSubtracted_thenCheckElementNotPresentInA() {
    Collection result = CollectionUtils.subtract(list1, list3);
    assertFalse(result.contains(customer1));
}

Количество раз, когда коллекция встречается в результате, равно количеству раз, когда она встречается в первой коллекции, минус количество раз, когда она встречается во второй коллекции.

4.9. Объединение коллекций

CollectionUtils.union выполняет объединение двух коллекций и возвращает коллекцию, содержащую все элементы, которые находятся либо в первой, либо во второй коллекции.

@Test
public void givenTwoLists_whenUnioned_thenCheckElementPresentInResult() {
    Collection union = CollectionUtils.union(list1, list2);
 
    assertTrue(union.contains(customer1));
    assertTrue(union.contains(customer4));
}

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

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

И мы закончили.

Мы рассмотрели некоторые из часто используемых методов CollectionUtils , что очень полезно, чтобы избежать шаблонности, когда мы работаем с коллекциями в наших проектах Java.

Как обычно, код доступен на GitHub.