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

Введение в коллекции Eclipse

Откройте для себя новый фреймворк коллекций от Eclipse.

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

1. Обзор

Eclipse Collections – это еще один улучшенный фреймворк коллекций для Java.

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

Библиотека предоставляет как изменяемые, так и неизменяемые реализации всех структур данных.

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

Давайте начнем с добавления следующей зависимости Maven в ваш pom.xml :

org.eclipse.collections
    eclipse-collections
    8.2.0

Мы можем найти последнюю версию библиотеки в Центральном репозитории Maven .

3. Общая Картина

3.1. Основные Типы Коллекций

Основными типами коллекций в коллекциях Eclipse являются:

  • Listerable – упорядоченная коллекция, которая поддерживает порядок вставки и позволяет дублировать элементы. Подинтерфейсы включают: MutableList , Список фиксированного размера и ImmutableList . Наиболее распространенной итерационной реализацией List является Fast List, который является подклассом MutableList
  • SetIterable – коллекция, которая не допускает дублирования элементов. Он может быть отсортирован или несортирован. Подинтерфейсы включают в себя: Сортируемый набор, повторяемый и Несортируемый. Наиболее распространенной несортированной Итерационной реализацией является Унифицированный набор
  • MapIterable – набор пар ключ/значение. Подинтерфейсы включают Изменяемую карту , Фиксированную карту и неизменяемую карту . Двумя распространенными реализациями являются Unified Map и MutableSortedMap . В то время как UnifiedMap не поддерживает никакого порядка, MutableSortedMap поддерживает естественный порядок элементов
  • BiMap – набор пар ключ/значение, которые можно перебирать в любом направлении. Растровое изображение расширяет интерфейс Map Iterable
  • Сумка – неупорядоченная коллекция, которая допускает дубликаты. Подинтерфейсы включают MutableBag и |/Мешок фиксированного размера . Наиболее распространенной реализацией является Хэштег StackIterable
  • – коллекция, которая поддерживает порядок “последний вход, первый выход”, повторяя элементы в обратном порядке вставки. Подинтерфейсы включают Изменяемый стек и Неизменяемый стек MultiMap
  • – набор пар ключ/значение, который допускает несколько значений для каждого ключа

3.2. Примитивные коллекции

Фреймворк также предоставляет огромный набор примитивных коллекций ; их реализации названы в честь типа, который они содержат. Для каждого типа из них существуют изменяемые, неизменяемые, синхронизированные и неизменяемые формы:

  • Примитивные Списки
  • Примитивные Наборы
  • Примитив Стеки
  • Примитивные Сумки
  • Примитив Карты
  • Интервал

Существует огромное количество примитивных форм карт, охватывающих все возможные комбинации ключей примитива или объекта и значений примитива или объекта.

Краткое примечание – IntInterval – это диапазон целых чисел, которые могут быть повторены с использованием значения шага.

4. Создание экземпляра коллекции

Чтобы добавить элементы в ArrayList или HashSet , мы создаем экземпляр коллекции, вызывая конструктор no-arg, а затем добавляем каждый элемент по одному.

Хотя мы все еще можем сделать это в коллекциях Eclipse, мы также можем создать экземпляр коллекции и предоставить все начальные элементы одновременно в одной строке.

Давайте посмотрим, как мы можем создать экземпляр Быстрого списка :

MutableList list = FastList.newListWith(
  "Porsche", "Volkswagen", "Toyota", "Mercedes", "Toyota");

Аналогично, мы можем создать экземпляр Унифицированного набора и добавить в него элементы, передав элементы в новый набор с помощью() статического метода:

Set comparison = UnifiedSet.newSetWith(
  "Porsche", "Volkswagen", "Toyota", "Mercedes");

Вот как мы можем создать экземпляр хэштега :

MutableBag bag = HashBag.newBagWith(
  "Porsche", "Volkswagen", "Toyota", "Porsche", "Mercedes");

Создание экземпляров карт и добавление к ним пар ключей и значений аналогично. Единственное различие заключается в том, что мы передаем пары ключей и значений в новую карту с помощью метода() в качестве реализаций интерфейса Pair .

Возьмем в качестве примера Унифицированную карту :

Pair pair1 = Tuples.pair(1, "One");
Pair pair2 = Tuples.pair(2, "Two");
Pair pair3 = Tuples.pair(3, "Three");

UnifiedMap map = new UnifiedMap<>(pair1, pair2, pair3);

Мы все еще можем использовать подход API коллекций Java:

UnifiedMap map = new UnifiedMap<>();

map.put(1, "one");
map.put(2, "two");
map.put(3, "three");

Поскольку неизменяемые коллекции не могут быть изменены, они не имеют реализаций методов, которые изменяют коллекции , таких как add() и remove() .

Неизменяемые коллекции, однако, позволяют нам вызывать эти методы, но вызовут Исключение UnsupportedOperationException если мы это сделаем.

5. Извлечение элементов из коллекций

Как и при использовании стандартных Списков , элементы коллекций Eclipse Списков могут быть извлечены по их индексу:

list.get(0);

А значения карт коллекций Eclipse можно получить с помощью их ключа:

map.get(0);

Методы getFirst() и getLast() могут использоваться для извлечения первого и последнего элементов списка соответственно. В случае других коллекций они возвращают первый и последний элемент, который будет возвращен итератором.

map.getFirst();
map.getLast();

Методы max() и min() можно использовать для получения максимальных и минимальных значений коллекции на основе естественного порядка.

map.max();
map.min();

6. Итерация по коллекции

Коллекции Eclipse предоставляют множество способов перебора коллекций. Давайте посмотрим, что это такое и как они работают на практике.

6.1. Фильтрация коллекций

Шаблон select возвращает новую коллекцию, содержащую элементы коллекции, удовлетворяющие логическому условию. По сути, это операция фильтрации.

Вот пример:

@Test
public void givenListwhenSelect_thenCorrect() {
    MutableList greaterThanThirty = list
      .select(Predicates.greaterThan(30))
      .sortThis();
    
    Assertions.assertThat(greaterThanThirty)
      .containsExactly(31, 38, 41);
}

То же самое можно сделать с помощью простого лямбда-выражения:

return list.select(i -> i > 30)
  .sortThis();

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

Давайте рассмотрим пример:

@Test
public void whenReject_thenCorrect() {
    MutableList notGreaterThanThirty = list
      .reject(Predicates.greaterThan(30))
      .sortThis();
    
    Assertions.assertThat(notGreaterThanThirty)
      .containsExactlyElementsOf(this.expectedList);
}

Здесь мы отвергаем все элементы, которые превышают 30.

6.2. Метод сбора()

Метод collect возвращает новую коллекцию, элементами которой являются результаты, возвращаемые предоставленным лямбда – выражением-по сути, это комбинация map() и collect() из Stream API.

Давайте посмотрим на это в действии:

@Test
public void whenCollect_thenCorrect() {
    Student student1 = new Student("John", "Hopkins");
    Student student2 = new Student("George", "Adams");
    
    MutableList students = FastList
      .newListWith(student1, student2);
    
    MutableList lastNames = students
      .collect(Student::getLastName);
    
    Assertions.assertThat(lastNames)
      .containsExactly("Hopkins", "Adams");
}

Созданная коллекция фамилии содержит фамилии, собранные из списка студенты .

Но, что делать, если возвращаемая коллекция является коллекцией коллекций, и мы не хотим поддерживать вложенную структуру?

Например, если у каждого студента есть несколько адресов, и нам нужна коллекция, содержащая адреса в виде Строк , а не коллекция коллекций, мы можем использовать метод flatCollect () .

Вот пример:

@Test
public void whenFlatCollect_thenCorrect() {
    MutableList addresses = students
      .flatCollect(Student::getAddresses);
    
    Assertions.assertThat(addresses)
      .containsExactlyElementsOf(this.expectedAddresses);
}

6.3. Обнаружение элементов

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

Давайте рассмотрим краткий пример:

@Test
public void whenDetect_thenCorrect() {
    Integer result = list.detect(Predicates.greaterThan(30));
    
    Assertions.assertThat(result)
      .isEqualTo(41);
}

То anySatisfy метод определяет, удовлетворяет ли какой-либо элемент коллекции логическому условию.

Вот пример:

@Test
public void whenAnySatisfiesCondition_thenCorrect() {
    boolean result = list.anySatisfy(Predicates.greaterThan(30));
    
    assertTrue(result);
}

Аналогично, все Удовлетворяют метод определяет, удовлетворяют ли все элементы коллекции логическому условию.

Давайте рассмотрим краткий пример:

@Test
public void whenAnySatisfiesCondition_thenCorrect() {
    boolean result = list.allSatisfy(Predicates.greaterThan(0));
    
    assertTrue(result);
}

6.4. Метод partition()

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

Давайте рассмотрим пример:

@Test
public void whenAnySatisfiesCondition_thenCorrect() {
    MutableList numbers = list;
    PartitionMutableList partitionedFolks = numbers
      .partition(i -> i > 30);
	
    MutableList greaterThanThirty = partitionedFolks
      .getSelected()
      .sortThis();
    MutableList smallerThanThirty = partitionedFolks
      .getRejected()
      .sortThis();
    
    Assertions.assertThat(smallerThanThirty)
      .containsExactly(1, 5, 8, 17, 23);
    Assertions.assertThat(greaterThanThirty)
      .containsExactly(31, 38, 41);
}

6.5. Ленивая итерация

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

@Test
public void whenLazyIteration_thenCorrect() {
    Student student1 = new Student("John", "Hopkins");
    Student student2 = new Student("George", "Adams");
    Student student3 = new Student("Jennifer", "Rodriguez");

    MutableList students = Lists.mutable
      .with(student1, student2, student3);
    LazyIterable lazyStudents = students.asLazy();
    LazyIterable lastNames = lazyStudents
      .collect(Student::getLastName);
    
    Assertions.assertThat(lastNames)
      .containsAll(Lists.mutable.with("Hopkins", "Adams", "Rodriguez"));
}

Здесь объект lazy Students не извлекает элементы списка students до тех пор, пока не будет вызван метод collect () .

7. Сопряжение элементов Коллекции

Метод zip() возвращает новую коллекцию, объединяя элементы двух коллекций в пары. Если какая-либо из двух коллекций длиннее, остальные элементы будут усечены.

Давайте посмотрим, как мы можем его использовать:

@Test
public void whenZip_thenCorrect() {
    MutableList numbers = Lists.mutable
      .with("1", "2", "3", "Ignored");
    MutableList cars = Lists.mutable
      .with("Porsche", "Volvo", "Toyota");
    MutableList> pairs = numbers.zip(cars);
    
    Assertions.assertThat(pairs)
      .containsExactlyElementsOf(this.expectedPairs);
}

Мы также можем связать элементы коллекции с их индексами, используя метод zipWithIndex() :

@Test
public void whenZip_thenCorrect() {
    MutableList cars = FastList
      .newListWith("Porsche", "Volvo", "Toyota");
    MutableList> pairs = cars.zipWithIndex();
    
    Assertions.assertThat(pairs)
      .containsExactlyElementsOf(this.expectedPairs);
}

8. Преобразование коллекций

Коллекции Eclipse предоставляют простые методы преобразования типа контейнера в другой. Это методы ToList() , toSet() , tobago() и to Map().

Давайте посмотрим, как мы можем их использовать:

public static List convertToList() {
    UnifiedSet cars = new UnifiedSet<>();
    
    cars.add("Toyota");
    cars.add("Mercedes");
    cars.add("Volkswagen");
    
    return cars.toList();
}

Давайте проведем наш тест:

@Test
public void whenConvertContainerToAnother_thenCorrect() {
    MutableList cars = (MutableList) ConvertContainerToAnother 
      .convertToList();
    
    Assertions.assertThat(cars)
      .containsExactlyElementsOf(
      FastList.newListWith("Volkswagen", "Toyota", "Mercedes"));
}

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

В этом руководстве мы увидели краткий обзор коллекций Eclipse и функций, которые они предоставляют.

Полная реализация этого учебника доступна на GitHub .