коллекции в java

Коллекции в java

Сегодня поговорим о коллекциях — структурах данных для хранения объектов. Самое короткое и простое определение коллекции: коллекция — это объект, который хранит другие объекты.

Для начала выясним: для чего нам нужны коллекции если у нас уже есть массивы, которые могут хранить другие объекты? Все дело в простоте и удобстве использования. Зачем изобретать велосипед, если его уже изобрели до нас. Мы просто берем и используем готовые решения, которые зачастую будут работать быстрее наших. Когда мы познакомимся с разными коллекциями, Вы поймете, что некоторые из них и строятся на массивах.

В чем еще преимущество использования коллекций:

  • удобство тестирования кода;
  • структуры данных на любой вкус и потребность;
  • повторное использование кода.

И это еще не полный список. По мере того, как Вы будете программировать, Вы сможете по настоящему оценить коллекции в java.

В Java есть два главных интерфейса от которых и наследуются все остальные классы коллекций: Collection, Map.

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

Map — хранит данные в виде пары «ключ-значение». Сегодня мы поговорим только о первом интерфейсе в связи с тем, что тема достаточно обширная и важная.

Интерфейс Collection наследуется другими интерфейсами, которые в свою очередь имплементируются классами, в которых реализована та или иная структура данных.

иерархия интерфейсов коллекции

На картинке выше Вы можете посмотреть иерархию интерфейсов коллекции и увидеть методы, которые у них есть. Как видим методов достаточно много и они очень полезные в работе с массивами данных.

От этих интерфейсов, как я уже говорил выше идет реализация классов.

классы унаследованы от коллекций

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

 

ArrayList — коллекция на основе массива. Имеет свойство изменять свой размер в зависимости от того удаляются или добавляются элементы.

array list1

LinkedList — коллекция на основе связанного списка. Элементы помещенные в данную коллекцию сохраняют свой порядок вставки. То есть, в каком порядке был вставлен элемент, в таком порядке он будет при выводе. Каждый элемент, который хранится в LinkedList, содержит ссылки на «соседей». Это упрощает добавление и удаление элементов в списке. Классы ArrayList и Vector предпочтительнее использовать для поиска элементов, потому что эти классы используют индексы для доступа к элементам. Однако вставка и удаление элементов для них будет медленнее, чем LinkedList.

linked list

Vector — тот же самый ArrayList с той разницей, что методы данной коллекции синхронизованы. То есть, потокобезобасны.

Stack — список, который реализует данные стека. Элементы размещаются по принципу LIFO (last-in, first-out) — последний пришел, первым ушел.

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

Код    
  1. package com.javamaster;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. public class ListExample {
  7.  
  8.     public static void main(String[] args) {
  9.         List<String> stringList = new ArrayList<>();//создание нового списка
  10.         stringList.add("Ivan");//добавление элементов
  11.         stringList.add("Elena");
  12.         stringList.add("Sergey");
  13.         System.out.println(stringList.size());//размер списка
  14.         stringList.get(1);//получения элемента по индексу (начинается с 0 элемента)
  15.         boolean isEmpty = stringList.isEmpty();//проверка списка на пустоту
  16.         System.out.println(isEmpty);
  17.         System.out.println("Просто вывод элементов");
  18.         stringList.stream().forEach(s-> System.out.println(s));//очень полезный метод стрим
  19.         stringList.stream().filter(s-> s.startsWith("I")).map(String::toLowerCase).forEach(System.out::println);
  20.     }
  21.  
  22. }

Результат работы программы:

Код    
  1. 3
  2. false
  3. Просто вывод элементов
  4. Ivan
  5. Elena
  6. Sergey
  7. ivan

Хотелось бы обратить внимание на метод stream, который является нововведением в Java 8. Если интересно, можно почитать отдельную статью о стрим апи.

Заменив ArrayList на LinkedList мы получаем тот же набор методов для этой структуры данных. Выбор в использовании структур зависит от требований программы. Преимущества каждой структуры мы описали выше. Что еще отличает LinkedList от ArrayList так это то, что на выходе Вы получите элементы в том же порядке, в котором Вы их добавляли в LinkedList. В то время, как ArrayList не гарантирует это. Те же самые методы будут работать для Vector и Stack.

 

Теперь перейдем к Set.

Set — коллекция, которая не содержит повторяющихся элементов.

HashSet — набор, в котором элементы хранятся в хеш-таблице. У элементов нет строгого порядка. HashSet использует метод hashCode своих элементов для определения их размещения в наборе.

LinkedHashSet — элементы хранятся в виде связанного списка. Только элементы хранятся в сортированном виде.

TreeSet — хранит элементы в структуре данных дерева, которая также сортируется и доступна для навигации. Методы добавление, удаление и получить элемент, гарантируют работу в log (n) времени, где n — количество элементов в дереве.

Код    
  1. package com.javamaster;
  2.  
  3.  
  4. import java.util.Set;
  5. import java.util.TreeSet;
  6.  
  7. public class SetExample {
  8.  
  9.     public static void main(String[] args) {
  10.         Set<Integer> set = new TreeSet<>();
  11.         set.add(20);
  12.         set.add(15);
  13.         set.add(30);
  14.         set.add(30);
  15.         set.add(30);
  16.         System.out.println(set);
  17.         set.remove(20);
  18.         System.out.println(set);
  19.     }
  20.  
  21. }

Результат работы программы:

[15, 20, 30]
[15, 30]

Как видим, добавление еще одной 30 не удалось, что подтверждает теорию о том, что в сет можно добавить только уникальные объекты. Методы данной структуры такие же как и List. Поэтому останавливаться здесь подробно не будем.

Еще предлагаю рассмотреть очередь (Queue).

Queue — коллекция, которая хранит элементы в определенном порядке, нужном для их обработки. Помимо основных методов Collection в этом интерфейсе добавлены дополнительные методы вставки, проверки, извлечения. В данной коллекции элементы обычно размещаются в порядке FIFO (first-in, first-out) — первым пришел, первым ушел.

Теперь к реализациям.

PriorityQueue — очередь, в которой элементы упорядочиваются на основании заданного вами параметра(в отличие от параметра на основе FIFO). Эта очередь упорядочивает элементы либо по их натуральному порядку (используя интерфейс Comparable), либо с помощью интерфейса Comparator, полученному в конструкторе.

Код    
  1. package com.javamaster;
  2.  
  3.  
  4. import java.util.Comparator;
  5. import java.util.PriorityQueue;
  6. import java.util.Queue;
  7.  
  8. public class QueueExample {
  9.  
  10.     public static void main(String[] args) {
  11.         Comparator<Integer> comparator = new Comparator<Integer>() {
  12.  
  13.             @Override
  14.             public int compare(Integer comp1, Integer comp2) {//настроили метод таким образом, что элементы будут добавляться в обратном порядке
  15.                 if( comp1 > comp2 ){
  16.                     return -1;
  17.                 }
  18.                 if( comp1 < comp2 ){
  19.                     return 1;
  20.                 }
  21.                 return 0;
  22.             }
  23.         };
  24.         Queue<Integer> priorityQueue = new PriorityQueue<>(10, comparator);
  25.         priorityQueue.add(7);
  26.         priorityQueue.add(4);
  27.         priorityQueue.add(9);
  28.         priorityQueue.add(1);
  29.         priorityQueue.add(80);
  30.         System.out.println(priorityQueue);
  31.     }
  32.  
  33. }

Результат работы программы: [80, 9, 1, 7]

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

Код    
  1. package com.javamaster;
  2.  
  3. import java.util.PriorityQueue;
  4. import java.util.Queue;
  5.  
  6. public class QueueExample {
  7.  
  8.     public static void main(String[] args) {
  9.         Queue<Integer> priorityQueue = new PriorityQueue<>();
  10.         priorityQueue.add(7);
  11.         priorityQueue.add(4);
  12.         priorityQueue.add(9);
  13.         priorityQueue.add(1);
  14.         priorityQueue.offer(80);//добавление
  15.         System.out.println(priorityQueue);
  16.         System.out.println(priorityQueue.poll());//удаление сверху
  17.         System.out.println(priorityQueue.peek());//получить верхний
  18.         System.out.println(priorityQueue);
  19.        
  20.     }
  21.  
  22. }

Результат работы:

[1, 4, 9, 7, 80]
1
4
[4, 7, 9, 80]

Пожалуй, на этом и закончим данную статью. О Map мы поговорим в другой раз. А сейчас, у Вас и так хватит работы, чтобы потренироваться в использовании прочитанного материала. Используйте коллекции, не бойтесь выхода за пределы как это было с массивами. Не следите за размерностью — об этом уже позаботились разработчики коллекций.

Добавить комментарий