1. введение
В этой краткой статье мы сосредоточимся на том, как использовать коллекцию Bag Apache.
Дальнейшее чтение:
Apache Commons BeanUtils
Apache Commons IO
Введение в текст Apache Commons
2. Зависимость Maven
Прежде чем мы начнем, нам нужно импортировать последние зависимости из Maven Central :
org.apache.commons commons-collections4 4.1
3. Сумки против коллекций
Проще говоря, Bag – это коллекция, которая позволяет хранить несколько предметов вместе с их количеством повторений:
public void whenAdded_thenCountIsKept() { Bagbag = new HashBag<>( Arrays.asList(1, 2, 3, 3, 3, 1, 4)); assertThat(2, equalTo(bag.getCount(1))); }
3.1. Нарушения Договора инкассации
При чтении документации API Bag мы можем заметить, что некоторые методы помечены как нарушающие стандартный контракт на сбор данных Java.
Например, когда мы используем add() API из коллекции Java, мы получаем true , даже если элемент уже находится в коллекции:
Collectioncollection = new ArrayList<>(); collection.add(1); assertThat(collection.add(1), is(true));
Тот же API из реализации Bag вернет false , когда мы добавим элемент, который уже доступен в коллекции:
Bagbag = new HashBag<>(); bag.add(1); assertThat(bag.add(1), is(not(true)));
Для решения этих проблем библиотека коллекций Apache предоставляет декоратор, называемый Collection Bag. Мы можем использовать это, чтобы сделать наши коллекции сумок совместимыми с контрактом Java Collection :
public void whenBagAddAPILikeCollectionAPI_thenTrue() { Bagbag = CollectionBag.collectionBag(new HashBag<>()); bag.add(1); assertThat(bag.add(1), is((true))); }
4. Реализация Пакетов
Теперь давайте рассмотрим различные реализации интерфейса Bag – в библиотеке коллекций Apache.
4.1. Хэштег
Мы можем добавить элемент и указать API количество копий этого элемента в нашей коллекции пакетов:
public void givenAdd_whenCountOfElementsDefined_thenCountAreAdded() { Bagbag = new HashBag<>(); bag.add(1, 5); // adding 1 five times assertThat(5, equalTo(bag.getCount(1))); }
Мы также можем удалить определенное количество копий или каждый экземпляр элемента из нашей сумки:
public void givenMultipleCopies_whenRemove_allAreRemoved() { Bagbag = new HashBag<>( Arrays.asList(1, 2, 3, 3, 3, 1, 4)); bag.remove(3, 1); // remove one element, two still remain assertThat(2, equalTo(bag.getCount(3))); bag.remove(1); // remove all assertThat(0, equalTo(bag.getCount(1))); }
4.2. Древесный мешок
Реализация Tree Bag работает как любое другое дерево, дополнительно сохраняя семантику Bag .
Мы можем естественным образом отсортировать массив целых чисел с помощью Tree Bag , а затем запросить количество экземпляров каждого отдельного элемента в коллекции:
public void givenTree_whenDuplicateElementsAdded_thenSort() { TreeBagbag = new TreeBag<>(Arrays.asList(7, 5, 1, 7, 2, 3, 3, 3, 1, 4, 7)); assertThat(bag.first(), equalTo(1)); assertThat(bag.getCount(bag.first()), equalTo(2)); assertThat(bag.last(), equalTo(7)); assertThat(bag.getCount(bag.last()), equalTo(3)); }
TreeBag реализует интерфейс SortedBag , все реализации этого интерфейса могут использовать декоратор CollectionSortedBag в соответствии с контрактом на коллекции Java:
public void whenTreeAddAPILikeCollectionAPI_thenTrue() { SortedBagbag = CollectionSortedBag.collectionSortedBag(new TreeBag<>()); bag.add(1); assertThat(bag.add(1), is((true))); }
4.3. SynchronizedSortedBag
Другой широко используемой реализацией Bag является SynchronizedSortedBag . Именно, это синхронизированный декоратор реализации SortedBag .
Мы можем использовать этот декоратор с нашим TreeBag (реализация SortedBag ) из предыдущего раздела для синхронизации доступа к нашей сумке:
public void givenSortedBag_whenDuplicateElementsAdded_thenSort() { SynchronizedSortedBagbag = SynchronizedSortedBag .synchronizedSortedBag(new TreeBag<>( Arrays.asList(7, 5, 1, 7, 2, 3, 3, 3, 1, 4, 7))); assertThat(bag.first(), equalTo(1)); assertThat(bag.getCount(bag.first()), equalTo(2)); assertThat(bag.last(), equalTo(7)); assertThat(bag.getCount(bag.last()), equalTo(3)); }
Мы можем использовать комбинацию API – Коллекций.synchronizedSortedMap() и TreeMap – для имитации того, что мы сделали здесь с SynchronizedSortedBag .
5. Заключение
В этом коротком уроке мы узнали об интерфейсе Bag и его различных реализациях.
Как всегда, код для этой статьи можно найти на GitHub .