Коллекции Java

Set, Map, Queue


Map

Интерфейс Map<K, V> представляет отображение (словарь), где каждый элемент представляет пару "ключ-значение". Map гарантирует, что все ключи уникальны.

HashMap — это структура из пар «ключ-значение» — или динамический массив ключей. Каждый элемент массива — это bucket (корзина), в каждом из которых хранится связанные списки со значением Map.Entry (если корзина пустая то связанный список будет состоять из одного элемента, а ссылаться этот элемент будет на null)


Создание коллекции

public static void main(String[] args) {

HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("One", 1);
hashMap.put("Two", 2);
hashMap.put("Three", 3);

for(Map.Entry<String, Integer> entry: hashMap.entrySet()){
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}

terminal:

One = 1
Two = 2
Three = 3



Добавление нового значения в HashMap
  •  Происходит вычисление K.hashCode()
  • Происходит вычисление корзины куда стоит положить данную пару
  • Далее мы обращаемся к связанному списку который храниться в корзине и сравниваем значение hashCode;
  • Если hashCode не совпали мы добавляем новую пару в конец;
  • Если hashCode совпали, то мы сравниваем K по equals;
  • Если объекты K равны то просто отбрасываем новое значение;
  • Если они отличаются то добавляем в конец списка.


Поиск, удаление и добавления элемента в среднем при работе с HashMap — O(1)

В HashMap для ключей всегда используйте immutable объекты

В отличие от коллекции HashMap в TreeMap все объекты автоматически сортируются по возрастанию их ключей (натуральный порядок или comparator)



Set

Коллекция реализующая интерфейс Set гарантирует уникальность элементов. Всегда переопределяйте методы hashCode() и equels()

HashSet это частный случай HashMap — вместо значения value используется константа


Создание коллекции
// Начальная ёмкость по умолчанию - 16, коэффициент загрузки - 0,75
HashSet defaultConstructor = new HashSet<>();

//Конструктор с заданной начальной ёмкостью. Коэффициент загрузки - 0,75
HashSet constructorWithCapacity = new HashSet<>(32);

// Конструктор с заданной ёмкостью и коэффициентом загрузки.
HashSet constructorWithCapacityFactor = new HashSet(32, 0.6f);

// Конструктор, добавляющий элемент из другой коллекции
HashSet fromCollection = new HashSet<>(defaultConstructor);


TreeSet
// Конструктор по умолчанию
TreeSet defaultConstructor = new TreeSet<>();

// Конструктор добавляющий элементы из другой коллекции
TreeSet fromCollection = new TreeSet(defaultConstructor);

//Конструктор создаёт пустое дерево, где все добавляемые элементы
// впоследствии будут отсортированы компаратором
TreeSet withComparator = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2){
return 0;
}
});


Queue

Очереди представляют структуру данных, работающую по принципу FIFO (first in — first out) — первый вошел, первый вышел.

Интерфейс Deque расширяет интерфейс Queue и определяет поведение двунаправленной очереди, которая работает как обычная однонаправленная очередь, либо как стек, действующий по принципу LIFO (последний вошел — первый вышел)

Первый элемент PriorityQueue или элемент из начала очереди — это наименьший элемент, определенный с использованием естественного порядка или компаратора. Если имеется несколько элементов с одинаковым весом (Comparator при сравнении возвращает 0), очередь может произвольно возвращать любого из них.

PriorityQueue<Integer> integerQueue = new PriorityQueue<>();
PriorityQueue<Integer> integerQueueWithComparator = new PriorityQueue<>((Integer c1, Integer c2) -> c2 - c1);

integerQueueWithComparator.add(3);
integerQueue.add(3);

integerQueueWithComparator.add(2);
integerQueue.add(2);

integerQueueWithComparator.add(1);
integerQueue.add(1);

System.out.println(integerQueue.poll());
System.out.println(integerQueue.poll());
System.out.println(integerQueue.poll());
System.out.println(integerQueueWithComparator.poll());
System.out.println(integerQueueWithComparator.poll());
System.out.println(integerQueueWithComparator.poll());

terminal:

1
2
3
3
2
1


Collections

Класс java.util.Collections это утилитарный класс (состоит исключительно из статических методов), предоставляющий дополнительные методы для работы с Collection и Map


Подведем итоги

● List — для организации хранения “обычных” списков;

● Set — для хранения уникальных объектов;

● Queue — для реализации задачи FIFO и LIFO;

● Map — для реализации ассоциативного массива. 




1 //В рамках выполнения задачи необходимо:
//● Создайте коллекцию мужских и женских имен с помощью интерфейса List
//● Отсортируйте коллекцию в алфавитном порядке
//● Отсортируйте коллекцию по количеству букв в слове
//● Разверните коллекцию


import java.util.*;

public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Alla");
names.add("Allana");
names.add("Bob");
names.add("A");

System.out.println("Изначально " + names);

Collections.sort(names);
System.out.println("Отсортировали в алфавитном " + names);

Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
});
System.out.println("По количеству букв " + names);

Collections.reverse(names);
System.out.println("Развернули " + names);

}

terminal:

Изначально [Alla, Allana, Bob, A]
Отсортировали в алфавитном [A, Alla, Allana, Bob]
По количеству букв [A, Bob, Alla, Allana]
Развернули [Allana, Alla, Bob, A]


//Создайте коллекцию мужских и женских имен с помощью интерфейса List -
// добавьте повторяющиеся значения

//● Получите уникальный список Set на основании List
//● Определите наименьший элемент (алфавитный порядок)
//● Определите наибольший элемент (по количеству букв в слове но в обратном
// порядке)
//● Удалите все элементы содержащие букву ‘A’


import java.util.*;

public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Gala");
names.add("Allana");
names.add("Bob");
names.add("A");
names.add("B");
names.add("Bob");
names.add("Gala");

System.out.println("Изначально " + names);

Set<String> namesSet = new HashSet<String>(names);
System.out.println("Уникальный список Set " + namesSet);

System.out.println("Наименьший элемент " + smallestElement(names));
System.out.println("Наибольший элемент " + largestElement(names));

System.out.println("Удалим с а " + deleteElement(names));
}

public static String smallestElement(List<String> list) {
String smallestElement = list.get(0);
for (int i = 0; i < list.size(); i++) {
if (smallestElement.length() > list.get(i).length())
smallestElement = list.get(i);
}
return smallestElement;
}

public static String largestElement(List<String> list) {
String largestElement = list.get(0);
for (int i = 0; i < list.size(); i++) {
if (largestElement.length() < list.get(i).length())
largestElement = list.get(i);
}
return largestElement;
}

public static List<String> deleteElement(List<String> list) {
List<String> newList = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
int a = list.get(i).toLowerCase().indexOf("a");
if(a < 0)
newList.add(list.get(i));
}
return newList;
}

Terminal:

Изначально [Gala, Allana, Bob, A, B, Bob, Gala]
Уникальный список Set [A, B, Bob, Allana, Gala]
Наименьший элемент A
Наибольший элемент Allana
Удалим с а [Bob, B, Bob]


DZ

Создать класс справочник сотрудников, который содержит внутри коллекцию сотрудников - каждый сотрудник должен иметь следующие атрибуты:
Табельный номер
Номер телефона
Имя
Стаж
Добавить метод, который ищет сотрудника по стажу (может быть список)
Добавить метод, который выводит номер телефона сотрудника по имени (может быть список)
Добавить метод, который ищет сотрудника по табельному номеру
Добавить метод добавление нового сотрудника в справочник сотрудников

Решение на github