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ępuje
  • size() to liczba elementów, isEmpty() sprawdza, czy lista jest pusta
  • remove(i) usuwa pozycję i, wszystko za nią przesuwa się do przodu
  • contains(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ści
  • LinkedHashSet: 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ąpiona
  • get(key) zwraca wartość albo null, jeśli klucza brakuje
  • getOrDefault(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 komunikatem unexpected type. W nawiasach ostrych stoją tylko klasy: List<Integer>, Map<String, Double>.

  • remove na List<Integer>

    Są dwie metody remove: z argumentem int usuwa 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ętli for z indeksem albo zbieraj elementy w nowej liście.

  • Brakujący klucz daje null

    int n = counts.get("dog"); kończy się błędem NullPointerException, jeśli klucza nie ma, bo null nie jest liczbą. Użyj getOrDefault(key, 0) albo najpierw sprawdź containsKey.

  • Kolejność w HashMap i HashSet

    HashMap i HashSet nie pamiętają, w jakiej kolejności coś dodałeś. Nie polegaj na tym przy wypisywaniu. Jeśli potrzebujesz kolejności, użyj LinkedHashSet albo LinkedHashMap.

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