ArrayList, HashSet i HashMap w Javie w prosty sposób
Zaktualizowano 22 października 2026
Listy i mapy w Javie rozwiązują problem tablic: tablica ma stały rozmiar. Często jednak nie wiesz z góry, ile będzie elementów: produkty w koszyku, piosenki na playliście. Java ma do tego gotowe kontenery, czyli kolekcje. Trzy najważniejsze to lista, zbiór (Set) i mapa. Wszystkie leżą w java.util i wymagają import.
ArrayList
ArrayList to jakby tablica, która rośnie. Jak takie listy są zbudowane od środka, pokazuje artykuł o listach, stosie i kolejce. W nawiasach ostrych podajesz, co trafi do środka (więcej w artykule o typach generycznych w Javie):
List<String> names = new ArrayList<>();
Po lewej stoi ogólny typ List, po prawej konkretna ArrayList. Puste nawiasy <> (tzw. „diament”) przejmują typ z lewej strony.
add(x)dodaje na końcu,get(i)czyta pozycjęi(od 0),set(i, x)zastępujesize()to liczba elementów,isEmpty()sprawdza, czy lista jest pustaremove(i)usuwa pozycjęi, wszystko za nią przesuwa się do przoducontains(x)szuka elementu
W nawiasach ostrych mogą stać tylko klasy. Dla liczb piszesz Integer zamiast int i Double zamiast double. Przy dodawaniu i odczycie Java zamienia je automatycznie. Listę, w przeciwieństwie do tablicy, możesz wypisać bezpośrednio. List.of("a", "b") szybko tworzy stałą listę, której potem nie da się zmienić.
import java.util.ArrayList;import java.util.List;
public class Main { public static void main(String[] args) { List<String> names = new ArrayList<>(); names.add("Ada"); names.add("Bob"); names.add("Cleo"); System.out.println(names); System.out.println("Size: " + names.size()); System.out.println("Index 1: " + names.get(1));
names.remove(0); names.add("Dan"); System.out.println(names); System.out.println(names.contains("Ada"));
List<Integer> squares = new ArrayList<>(); for (int i = 1; i <= 5; i++) { squares.add(i * i); } int sum = 0; for (int n : squares) { sum += n; } System.out.println(squares + " sum " + sum); }}Set: każdy element tylko raz
Zbiór (Set) zawiera każdy element najwyżej raz. add zwraca false, jeśli element już w nim jest, i zostawia zbiór bez zmian. Dzięki temu usuniesz duplikaty albo policzysz różne wartości.
HashSet: szybki, ale bez stałej kolejnościLinkedHashSet: zachowuje kolejność, w jakiej elementy były dodawane
Zbiór nie ma get(i). Jeśli znowu potrzebujesz listy, przekaż zbiór do konstruktora: new ArrayList<>(set).
import java.util.ArrayList;import java.util.LinkedHashSet;import java.util.List;import java.util.Set;
public class Main { public static void main(String[] args) { List<String> signUps = List.of("Mia", "Leo", "Mia", "Ana", "Leo"); Set<String> guests = new LinkedHashSet<>(); for (String name : signUps) { boolean added = guests.add(name); if (!added) { System.out.println(name + " is already on the list"); } } System.out.println(guests); System.out.println(guests.size() + " guests"); System.out.println(guests.contains("Ana"));
List<String> list = new ArrayList<>(guests); System.out.println("Last: " + list.get(list.size() - 1)); }}HashMap: klucz i wartość
Mapa przechowuje pary klucz–wartość, na przykład imię → numer telefonu. Dlaczego HashMap znajduje elementy tak szybko, wyjaśnia artykuł o haszowaniu i grafach. Map<String, String> podaje oba typy.
put(key, value)zapisuje; jeśli klucz już istnieje, stara wartość zostaje zastąpionaget(key)zwraca wartość albonull, jeśli klucza brakujegetOrDefault(key, fallback)zwraca w takim przypadku wartość zastępczącontainsKey(key),size(),keySet()dla wszystkich kluczy
Żeby liczyć wystąpienia, bierzesz dotychczasową liczbę (albo 0) i zapisujesz ją powiększoną o jeden, jak w przykładzie. Wartości mogą same być listami: Map<String, List<Integer>> przechowuje dla każdego imienia listę ocen.
import java.util.HashMap;import java.util.Map;
public class Main { public static void main(String[] args) { Map<String, String> phone = new HashMap<>(); phone.put("Ada", "0151 123"); phone.put("Bob", "0160 456"); phone.put("Ada", "0170 789"); System.out.println(phone.get("Ada")); System.out.println(phone.get("Eve")); System.out.println(phone.getOrDefault("Eve", "unknown")); System.out.println(phone.containsKey("Bob")); System.out.println(phone.size() + " entries");
String text = "the cat and the hat and the bat"; Map<String, Integer> counts = new HashMap<>(); for (String word : text.split(" ")) { counts.put(word, counts.getOrDefault(word, 0) + 1); } System.out.println("the: " + counts.get("the")); System.out.println("and: " + counts.get("and")); System.out.println("cat: " + counts.get("cat")); }}Typowe błędy
List<int>
Kompilator odrzuca
List<int>z komunikatemunexpected type. W nawiasach ostrych stoją tylko klasy:List<Integer>,Map<String, Double>.remove na List<Integer>
Są dwie metody
remove: z argumentemintusuwa pozycję, z obiektem usuwa element. Przy liście liczb to pułapka:List<Integer> numbers = new ArrayList<>(List.of(10, 20, 30));numbers.remove(1); // removes position 1: [10, 30]numbers.remove(Integer.valueOf(10)); // removes the value 10: [30]Zmiana listy wewnątrz for-each
Jeśli usuwasz albo dodajesz elementy, podczas gdy pętla for-each przechodzi po tej samej liście, program kończy się błędem
ConcurrentModificationException. Użyj zwykłej pętliforz indeksem albo zbieraj elementy w nowej liście.Brakujący klucz daje null
int n = counts.get("dog");kończy się błędemNullPointerException, jeśli klucza nie ma, bonullnie jest liczbą. UżyjgetOrDefault(key, 0)albo najpierw sprawdźcontainsKey.Kolejność w HashMap i HashSet
HashMapiHashSetnie pamiętają, w jakiej kolejności coś dodałeś. Nie polegaj na tym przy wypisywaniu. Jeśli potrzebujesz kolejności, użyjLinkedHashSetalboLinkedHashMap.
Zadania z tego tematu
Przećwicz to, czego się nauczyłeś, od razu w przeglądarce. Testy natychmiast sprawdzają twoje rozwiązanie.
Powiązane artykuły
- Generyki i nowoczesna JavaTypy generyczne w Javie w prosty sposób: klasy i metody generyczne, var, instanceof, Optional i sealed z przykładami. Do tego typowe błędy, np. Box<int>.Czytaj artykuł
- Lambdy i strumienieLambdy i strumienie w Javie w prosty sposób: filter, map, reduce, Comparator i groupingBy z przykładami. Do tego typowe błędy z toList() i reversed().Czytaj artykuł
- Haszowanie i grafyTablica mieszająca, przeszukiwanie wszerz i w głąb oraz algorytm Dijkstry w Javie: przykłady kodu, złożoność i typowe błędy prosto wyjaśnione.Czytaj artykuł