- Добавлять, удалять, изменять и сортировать элементы в
ArrayList - Хранить пары «ключ–значение» в
HashMap, а уникальные значения — вHashSet - Понимать обобщённые типы вроде
List<String>и писать простой обобщённый класс
Длина массива фиксирована: в массив на 5 ячеек нельзя добавить 6-й элемент. Но корзина покупок, сообщения в чате или список игроков постоянно растут и уменьшаются. Для этого в Java есть готовые коллекции — гибкие структуры данных из пакета java.util.
ArrayList: растущий список
ArrayList работает с индексами, как массив, но сам растёт по мере добавления элементов. <String> в угловых скобках указывает, какого типа элементы хранит список. Переменную обычно объявляют с типом общего интерфейса List, а справа пишут пустые <> («ромб»), чтобы не повторять тип.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> cities = new ArrayList<>();
cities.add("Baku");
cities.add("Ganja");
cities.add("Lankaran");
cities.add(1, "Shaki");
System.out.println(cities + " size=" + cities.size());
System.out.println(cities.get(0) + ", " + cities.contains("Ganja"));
cities.remove("Lankaran");
cities.set(0, "Sumgait");
Collections.sort(cities);
System.out.println(cities);
for (String c : cities) {
System.out.print(c.toUpperCase() + " ");
}
System.out.println();
}
}[Baku, Shaki, Ganja, Lankaran] size=4 Baku, true [Ganja, Shaki, Sumgait] GANJA SHAKI SUMGAIT
| Метод | Что делает |
|---|---|
add(x), add(i, x) | добавляет в конец или на позицию i |
get(i), set(i, x) | читает или заменяет элемент с индексом i |
remove(i), remove(x) | удаляет по индексу или по значению |
size(), isEmpty() | количество элементов, пуст ли список |
contains(x), indexOf(x) | есть ли элемент и где он |
list.contains(x) проверяет элементы по одному — именно как этот линейный поиск. Чем длиннее список, тем дольше поиск. Если часто нужно спрашивать «есть ли такой элемент?», гораздо быстрее HashSet, о котором ниже.HashMap: ключи и значения
Отображение (Map) связывает каждый ключ со значением — как словарь: слово → толкование, страна → столица. Ключи не повторяются: если снова вызвать put с тем же ключом, старое значение заменится. get возвращает null, если ключ не найден, а getOrDefault — запасное значение, которое ты укажешь.
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
Map<String, String> capitals = new HashMap<>();
capitals.put("Azerbaijan", "Baku");
capitals.put("Turkiye", "Ankara");
capitals.put("Georgia", "Tbilisi");
System.out.println(capitals.get("Turkiye"));
System.out.println(capitals.get("France"));
System.out.println(capitals.getOrDefault("France", "unknown"));
System.out.println(capitals.containsKey("Georgia") + " " + capitals.size());
String text = "to be or not to be";
Map<String, Integer> counts = new TreeMap<>();
for (String word : text.split(" ")) {
counts.put(word, counts.getOrDefault(word, 0) + 1);
}
System.out.println(counts);
for (Map.Entry<String, Integer> e : counts.entrySet()) {
System.out.println(e.getKey() + " -> " + e.getValue());
}
}
}Ankara
null
unknown
true 3
{be=2, not=1, or=1, to=2}
be -> 2
not -> 1
or -> 1
to -> 2Во второй части считаем слова: split(" ") разбивает текст на слова, и счётчик каждого слова растёт на 1. Здесь использован TreeMap — это тоже Map, но он хранит ключи в алфавитном порядке. HashMap хранит элементы без определённого порядка: он быстрее, но порядок вывода заранее неизвестен. entrySet() позволяет перебрать в цикле все пары «ключ–значение».
HashSet: уникальные элементы
Множество (Set) хранит каждый элемент только один раз. add возвращает true, если элемент добавлен, и false, если он уже был. В HashSet метод contains работает намного быстрее, чем в списке: он не перебирает элементы, а с помощью хеш-кода сразу смотрит в нужное место.
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
List<String> visitors = List.of("Leyla", "Murad", "Leyla", "Aysel", "Murad");
Set<String> unique = new HashSet<>(visitors);
System.out.println(visitors.size() + " visits, " + unique.size() + " people");
System.out.println(unique.add("Elvin") + " " + unique.add("Leyla"));
System.out.println(unique.contains("Aysel"));
System.out.println(new TreeSet<>(unique));
}
}5 visits, 3 people true false true [Aysel, Elvin, Leyla, Murad]
Дженерики
List<String>, Map<String, Integer> — это обобщённые типы (дженерики). Благодаря им компилятор не позволит положить в список элемент не того типа, и при извлечении элемента не нужно приводить тип. Коллекции хранят только объекты, поэтому вместо примитивов пишут классы-обёртки: Integer, Double, Boolean, Character. Преобразование int ↔ Integer Java выполняет автоматически (autoboxing).
import java.util.ArrayList;
import java.util.List;
public class Main {
static <T> T last(List<T> list) {
return list.get(list.size() - 1);
}
public static void main(String[] args) {
Pair<String, Integer> p = new Pair<>("Aysel", 95);
System.out.println(p.first() + " scored " + p.second());
List<Integer> nums = new ArrayList<>(List.of(10, 20, 30));
int total = 0;
for (int n : nums) {
total += n;
}
System.out.println(total + " " + last(nums) + " " + last(List.of("a", "b")));
nums.remove(1);
System.out.println(nums);
nums.remove(Integer.valueOf(10));
System.out.println(nums);
}
}
class Pair<A, B> {
private final A first;
private final B second;
Pair(A first, B second) {
this.first = first;
this.second = second;
}
A first() { return first; }
B second() { return second; }
}Aysel scored 95 60 30 b [10, 30] [30]
class Pair<A, B>— обобщённый класс:AиB— параметры типа, которые при создании объекта заменяются конкретными типами.static <T> T last(List<T> list)— обобщённый метод: один и тот же код работает и для спискаInteger, и для спискаString.List.of(...)одной строкой создаёт неизменяемый список; если его нужно менять, пишиnew ArrayList<>(List.of(...)).
Главное
ArrayList— список переменного размера:add,get,set,remove,size.HashMapсвязывает ключи со значениями; ключи уникальны, аgetвозвращаетnull, если ключа нет.HashSetхранит только уникальные элементы и очень быстро выполняетcontains.HashMapиHashSetне сохраняют порядок; отсортированные варианты —TreeMapиTreeSet.- Дженерики (
List<String>) обеспечивают безопасность типов; вместо примитивов используют классы-обёрткиInteger,Double.
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.
ArrayList отличается от массива?