Wykład 14
Box
, która może przechowywać obiekt dowolnego typu. Klasa powinna zawierać metodę set
, aby ustawić obiekt, oraz metodę get
, aby go pobrać.Napisz generyczną metodę isEqual
, która przyjmuje dwa dowolne obiekty tego samego typu i zwraca true
, jeśli są one równe, w przeciwnym razie false
.
Stwórz klasę generyczną Counter<T>
, która będzie zliczać ilość dodanych elementów określonego typu. Klasa powinna mieć metodę add(T element)
, która dodaje element do wewnętrznej struktury, oraz metodę getCount()
, która zwraca liczbę dodanych elementów.
Napisz statyczną metodę generyczną swap
, która przyjmuje tablicę dowolnego typu i dwa indeksy, a następnie zamienia miejscami elementy w tej tablicy pod wskazanymi indeksami. Metoda powinna działać dla tablicy każdego typu. Przykładowe wywołanie metody: swap(myArray, 0, 2);
, gdzie myArray
to tablica typu Integer[]
lub dowolnego innego typu. Zabezpiecz metodę tak, aby nie można było jej wywołać z indeksami spoza zakresu tablicy, jak również dla null
i pustej tablicy (o zerowej liczbie elementów).
Napisz statyczną metodę generyczną maxValue
, która przyjmuje tablicę elementów typu generycznego T
, gdzie T
rozszerza Comparable<T>
. Metoda powinna zwracać największy element z tablicy. Upewnij się, że metoda nie akceptuje pustej tablicy (o zerowej liczbie elementów). Przetestuj metodę na tablicach zawierających różne typy porównywalnych obiektów, jak Integer
, Float
, czy String
. Stwórz klasę Vehicle
z polami model
i speed
, implementującą generyczny Comparable
, i przetestuj metodę maxValue
na tablicy obiektów Vehicle
.
W kontekście programowania obiektowego w Javie, kolekcja (ang. ‘collection’) odnosi się do struktury danych, która grupuje obiekty w pojedynczym zbiorniku. Java oferuje szeroki zestaw klas kolekcji w ramach Java Collections Framework, które pozwalają na przechowywanie, przetwarzanie i manipulację zbiorami danych w elastyczny i efektywny sposób.
Uwaga: w internecie można znaleźć misz masz własności, w szczególności pod kątem złożoności obliczeniowej. Warygodnym źródłem jest dokumentacha.
Książka w trakcie powstawania:
Maurice Naftalin, Philip Wadler, Java Generics and Collections, O’Reilly Media, Inc. - wydanie drugie planowane na czerwiec 2024, choć można znaleźć fragemty w internecie.
Ilustacji z książki: Cay S. Horstmann, Java. Podstawy. Wydanie XII , Wyd. Helion, 2021.
Iterator
Collection
ArrayList
LinkedList
HashSet
TreeSet
HashMap
TreeMap
Iterator
Generyczny interfejs Iterator<E>
jest fundamentalnym elementem Java Collections Framework, umożliwiającym przeglądanie elementów kolekcji, takich jak listy, zbiory (sets) czy kolejki (queues).
Metody:
boolean hasNext()
: Ta metoda sprawdza, czy w kolekcji są jeszcze jakieś elementy do przetworzenia. Zwraca true
, jeśli kolekcja posiada kolejne elementy.E next()
: Zwraca następny element z kolekcji. Gdy nie ma więcej elementów, rzucany jest wyjątek NoSuchElementException
.void remove()
: Usuwa z kolekcji ostatni element zwrócony przez metodę next()
. Metoda ta może rzucić wyjątek UnsupportedOperationException
, jeśli operacja usuwania nie jest wspierana przez daną kolekcję.forEachRemaining(Consumer<? super E> action)
: Służy do wykonania danej akcji dla każdego pozostałego elementu w iteracji, zaczynając od aktualnej pozycji iteratora.Collection
Interfejs Collection<E>
jest jednym z podstawowych interfejsów w Java Collections Framework i służy jako korzeń dla innych interfejsów kolekcji, takich jak List
, Set
, czy Queue
. Jest to generyczny interfejs, co oznacza, że można go parametryzować różnymi typami obiektów (reprezentowanymi przez E
).
Metody:
Interfejs Collection<E>
w Javie zawiera wiele metod, które są fundamentalne dla manipulowania i dostępu do kolekcji danych. Oto niektóre z najpopularniejszych i najczęściej używanych metod tego interfejsu:
add(E e)
: Dodaje określony element do kolekcji. Zwraca true
, jeśli kolekcja zmieniła się w wyniku wywołania tej metody.
addAll(Collection<? extends E> c)
: Dodaje wszystkie elementy z określonej kolekcji do bieżącej kolekcji. Zwraca true
, jeśli bieżąca kolekcja zmieniła się w wyniku wywołania tej metody.
clear()
: Usuwa wszystkie elementy z kolekcji. Po wykonaniu tej metody kolekcja jest pusta.
contains(Object o)
: Sprawdza, czy kolekcja zawiera określony element. Zwraca true
, jeśli kolekcja zawiera przynajmniej jedno wystąpienie określonego elementu.
containsAll(Collection<?> c)
: Sprawdza, czy kolekcja zawiera wszystkie elementy z określonej kolekcji.
isEmpty()
: Sprawdza, czy kolekcja jest pusta (nie zawiera żadnych elementów). Zwraca true
, jeśli kolekcja nie zawiera żadnych elementów.
iterator()
: Zwraca iterator do przeglądania elementów w kolekcji. Iterator pozwala na sekwencyjne przechodzenie przez elementy kolekcji.
remove(Object o)
: Usuwa jedno wystąpienie określonego elementu z kolekcji, jeśli istnieje. Zwraca true
, jeśli kolekcja zmieniła się w wyniku wywołania tej metody.
removeAll(Collection<?> c)
: Usuwa z tej kolekcji wszystkie jej elementy, które są zawarte w określonej kolekcji.
retainAll(Collection<?> c)
: Zachowuje tylko te elementy w kolekcji, które są zawarte w określonej kolekcji. Innymi słowy, usuwa z tej kolekcji wszystkie elementy, których nie ma w określonej kolekcji.
size()
: Zwraca liczbę elementów w kolekcji.
toArray()
: Zwraca tablicę zawierającą wszystkie elementy kolekcji.
Możliwość tworzenie algorytmów generycznych opartych na kolekcjach.
Projekt W14, example25
package example25;
import java.util.*;
public class Test25 {
public static void main(String[] args) {
Integer[] numbers = {1, -2, 33, 76, 5};
System.out.println(max(Arrays.asList(numbers)));
LinkedList<String> strings = new LinkedList<>();
strings.add("one");
strings.add("two");
strings.add("three");
System.out.println(max(strings));
}
public static <T extends Comparable<T>> T max(Collection<T> c) {
if (c == null || c.isEmpty()) {
throw new NoSuchElementException("Collection is null or empty");
}
Iterator<T> iterator = c.iterator();
T largest = iterator.next();
while (iterator.hasNext()) {
T next = iterator.next();
if (largest.compareTo(next) < 0) {
largest = next;
}
}
return largest;
}
}
LinkedList
(lista powiązana)LinkedList<E>
w Javie jest implementacją listy powiązanej, która jest częścią Java Collection Framework. Jest to dynamiczna struktura danych, co oznacza, że może dynamicznie rosnąć i zmniejszać się, dodając lub usuwając elementy.
Implementacja: LinkedList
implementuje interfejsy List
, Deque
, i Queue
. Może więc działać jako lista, dwustronna kolejka (deque) lub kolejka (queue).
Węzły: Każdy element (węzeł) w LinkedList
przechowuje dane oraz referencje do poprzedniego i następnego elementu, co umożliwia łatwe dodawanie i usuwanie elementów.
Dostęp do elementów: Dostęp do elementów w LinkedList
jest sekwencyjny, co oznacza, że czas dostępu do elementów jest proporcjonalny do ich położenia.
Złożoność czasowa: Dodawanie/usuwanie na początku lub końcu listy ma złożoność O(1). Wyszukiwanie, dodawanie lub usuwanie elementów w środku listy ma złożoność O(n), gdzie n to liczba elementów w liście.
Użycie pamięci: Każdy element listy wiązanej wymaga dodatkowej pamięci na przechowywanie referencji do następnego i poprzedniego elementu, co czyni LinkedList
bardziej wymagającą pod względem pamięci w porównaniu z ArrayList
.
Metody: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/LinkedList.html
void add(int index, E element): Wstawia określony element na określonej pozycji na liście.
boolean add(E e): Dodaje określony element na końcu listy.
boolean addAll(int index, Collection<? extends E> c): Wstawia wszystkie elementy z określonej kolekcji do tej listy, zaczynając od określonej pozycji.
boolean addAll(Collection<? extends E> c): Dodaje wszystkie elementy z określonej kolekcji na końcu tej listy, w kolejności zwracanej przez iterator danej kolekcji.
void addFirst(E e): Wstawia określony element na początku listy.
void addLast(E e): Dodaje określony element na końcu listy.
void clear(): Usuwa wszystkie elementy z tej listy.
Object clone(): Zwraca płytką kopię tej listy LinkedList
.
boolean contains(Object o): Zwraca true
, jeśli lista zawiera określony element.
Iterator
E element(): Pobiera, ale nie usuwa, głowę (pierwszy element) tej listy.
E get(int index): Zwraca element na określonej pozycji na liście.
E getFirst(): Zwraca pierwszy element na liście.
E getLast(): Zwraca ostatni element na liście.
int indexOf(Object o): Zwraca indeks pierwszego wystąpienia określonego elementu na liście, lub -1, jeśli lista nie zawiera tego elementu.
int lastIndexOf(Object o): Zwraca indeks ostatniego wystąpienia określonego elementu na liście, lub -1, jeśli lista nie zawiera tego elementu.
ListIterator
boolean offer(E e): Dodaje określony element jako ogon (ostatni element) tej listy.
boolean offerFirst(E e): Wstawia określony element na początku tej listy.
boolean offerLast(E e): Wstawia określony element na końcu tej listy.
E peek(): Pobiera, ale nie usuwa, głowę (pierwszy element) tej listy.
E peekFirst(): Pobiera, ale nie usuwa, pierwszy element tej listy lub zwraca null
, jeśli lista jest pusta.
E peekLast(): Pobiera, ale nie usuwa, ostatni element tej listy lub zwraca null
, jeśli lista jest pusta.
E poll(): Pobiera i usuwa głowę (pierwszy element) tej listy.
E pollFirst(): Pobiera i usuwa pierwszy element tej listy, lub zwraca null
, jeśli lista jest pusta.
E pollLast(): Pobiera i usuwa ostatni element tej listy, lub zwraca null
, jeśli lista jest pusta.
E pop(): Usuwa i zwraca element ze stosu reprezentowanego przez tę listę.
void push(E e): Wstawia element na stos reprezentowany przez tę listę.
E remove(): Pobiera i usuwa głowę (pierwszy element) tej listy.
E remove(int index): Usuwa element na określonej pozycji na liście.
boolean remove(Object o): Usuwa pierwsze wystąpienie określonego elementu z tej listy, jeśli jest obecny.
E removeFirst(): Usuwa i zwraca pierwszy element z tej listy.
boolean removeFirstOccurrence(Object o): Usuwa pierwsze wystąpienie określonego elementu na tej liście (podczas przeglądania listy od głowy do ogona).
E removeLast(): Usuwa i zwraca ostatni element z tej listy.
boolean removeLastOccurrence(Object o): Usuwa ostatnie wystąpienie określonego elementu na tej liście (podczas przeglądania listy od głowy do ogona).
LinkedList
E set(int index, E element): Zastępuje element na określonej pozycji na liście określonym elementem.
int size(): Zwraca liczbę elementów na tej liście.
SpliteratorSpliterator
po elementach tej listy.
Object[] toArray(): Zwraca tablicę zawierającą wszystkie elementy tej listy w odpowiedniej kolejności (od pierwszego do ostatniego elementu).
Projekt W14, example26
package example26;
import java.util.LinkedList;
public class LinkedListExample {
public static void main(String[] args) {
// Tworzenie trzech różnych LinkedList
LinkedList<String> list1 = new LinkedList<>();
LinkedList<Integer> list2 = new LinkedList<>();
LinkedList<Double> list3 = new LinkedList<>();
// Dodawanie elementów
list1.add("Jabłko");
list1.add("Banana");
list2.add(1);
list2.add(2);
list3.add(1.1);
list3.add(2.2);
// Dodawanie na początku i na końcu
list1.addFirst("Pomarańcza");
list1.addLast("Gruszka");
// Usuwanie elementów
list2.removeFirst();
list2.removeLast();
// Pobieranie i ustawianie wartości
String firstItem = list1.getFirst();
list1.set(1, "Kokos");
// Rozmiar listy
int size1 = list1.size();
int size2 = list2.size();
// Sprawdzanie czy lista zawiera element
boolean containsApple = list1.contains("Jabłko");
// Iteracja przez listę
for(String item : list1) {
System.out.println(item);
}
}
}
HashSet
(zbiór mieszający)HashSet<E>
to implementacja zbioru, która jest częścią Java Collections Framework. Jest to kolekcja, która przechowuje unikalne elementy, nie dopuszczając duplikatów.
Unikalność: HashSet
przechowuje tylko unikalne elementy. Próba dodania duplikatu nie spowoduje błędu, ale element nie zostanie dodany.
Brak kolejności: Elementy w HashSet
nie są przechowywane w żadnej określonej kolejności. Kolejność elementów może się różnić przy każdym uruchomieniu programu.
Szybkość działania: HashSet
zapewnia stały czas potrzebny do operacji dodawania, usuwania i sprawdzania, czy element istnieje, co sprawia, że jest bardzo wydajny.
Null: HashSet
pozwala na przechowywanie maksymalnie jednego elementu null
.
Implementacja: HashSet
jest zaimplementowany na bazie tablicy mieszającej (HashMap
), gdzie klucze to elementy zbioru, a wartości są obiektami-pustymi miejscami.
Brak gwarancji kolejności: Kolejność elementów w HashSet
może się zmieniać w miarę dodawania lub usuwania elementów.
Metody: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/HashSet.html
boolean add(E e): Dodaje określony element do tego zbioru, jeśli jeszcze się w nim nie znajduje.
void clear(): Usuwa wszystkie elementy z tego zbioru.
Object clone(): Zwraca płytką kopię tej instancji HashSet
: same elementy nie są klonowane.
boolean contains(Object o): Zwraca true
, jeśli ten zbiór zawiera określony element.
boolean isEmpty(): Zwraca true
, jeśli ten zbiór nie zawiera żadnych elementów.
Iterator
static HashSet
odpowiedni dla oczekiwanej liczby elementów.
boolean remove(Object o): Usuwa określony element z tego zbioru, jeśli jest obecny.
int size(): Zwraca liczbę elementów w tym zbiorze (jego moc).
SpliteratorSpliterator
po elementach tego zbioru.
Object[] toArray(): Zwraca tablicę zawierającą wszystkie elementy tej kolekcji.
Projekt W14, example27
package example27;
import java.util.HashSet;
public class HashSetExample {
public static void main(String[] args) {
// Tworzenie HashSet
HashSet<String> stringSet = new HashSet<>();
HashSet<Integer> intSet = new HashSet<>();
// Dodawanie elementów
stringSet.add("Jabłko");
stringSet.add("Banana");
intSet.add(1);
intSet.add(2);
// Sprawdzanie, czy zbiór zawiera element
boolean containsBanana = stringSet.contains("Banana");
// Usuwanie elementu
stringSet.remove("Jabłko");
// Sprawdzanie, czy zbiór jest pusty
boolean isEmptyStringSet = stringSet.isEmpty();
// Pobieranie rozmiaru zbioru
int sizeIntSet = intSet.size();
// Iteracja przez zbiór
for(String s : stringSet) {
System.out.println(s);
}
// Czyszczenie zbioru
intSet.clear();
}
}
TreeSet
(zbiór drzewiasty)TreeSet<E>
to implementacja zbioru oparta na drzewie czerwono-czarnym, będąca częścią Java Collections Framework. Jest to posortowana i automatycznie sortująca się kolekcja unikalnych elementów.
Sortowanie: Elementy w TreeSet
są zawsze posortowane według naturalnego porządku lub według Comparatora dostarczonego przy tworzeniu zbioru. To oznacza, że elementy są automatycznie sortowane w momencie ich dodawania.
Unikalność: Podobnie jak HashSet
, TreeSet
przechowuje tylko unikalne elementy, nie dopuszczając duplikatów.
Wykonanie: Dzięki strukturze drzewa czerwono-czarnego, operacje takie jak wyszukiwanie, dodawanie i usuwanie elementów mają złożoność czasową logarytmiczną O(log n), co jest bardziej efektywne niż liniowa złożoność niektórych innych struktur danych dla dużych zestawów danych.
Null: TreeSet
zwykle nie akceptuje wartości null
jako elementów. Próba dodania null
może skutkować NullPointerException
, w zależności od użytego Comparatora.
Iteracja: Iteracja przez elementy TreeSet
odbywa się w uporządkowany sposób, co jest korzystne, gdy potrzebna jest uporządkowana prezentacja danych.
Metody: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/TreeSet.html
boolean add(E e): Dodaje określony element do tego zbioru, jeśli jeszcze się w nim nie znajduje.
boolean addAll(Collection<? extends E> c): Dodaje wszystkie elementy z określonej kolekcji do tego zbioru.
void addFirst(E e): Rzuca wyjątek UnsupportedOperationException
.
void addLast(E e): Rzuca wyjątek UnsupportedOperationException
.
E ceiling(E e): Zwraca najmniejszy element w tym zbiorze większy lub równy podanemu elementowi, lub null
, jeśli taki element nie istnieje.
void clear(): Usuwa wszystkie elementy z tego zbioru.
Object clone(): Zwraca płytką kopię tej instancji TreeSet
.
Comparator<? super E> comparator(): Zwraca komparator używany do porządkowania elementów w tym zbiorze, lub null
, jeśli zbiór używa naturalnego porządkowania swoich elementów.
boolean contains(Object o): Zwraca true
, jeśli ten zbiór zawiera określony element.
Iterator
NavigableSet
E first(): Zwraca pierwszy (najniższy) element aktualnie w tym zbiorze.
E floor(E e): Zwraca największy element w tym zbiorze mniejszy lub równy podanemu elementowi, lub null
, jeśli taki element nie istnieje.
SortedSet
NavigableSettrue
) toElement.
E higher(E e): Zwraca najmniejszy element w tym zbiorze ściśle większy niż podany element, lub null
, jeśli taki element nie istnieje.
boolean isEmpty(): Zwraca true
, jeśli ten zbiór nie zawiera żadnych elementów.
Iterator
E last(): Zwraca ostatni (najwyższy) element aktualnie w tym zbiorze.
E lower(E e): Zwraca największy element w tym zbiorze ściśle mniejszy niż podany element, lub null
, jeśli taki element nie istnieje.
E pollFirst(): Pobiera i usuwa pierwszy (najniższy) element, lub zwraca null
, jeśli ten zbiór jest pusty.
E pollLast(): Pobiera i usuwa ostatni (najwyższy) element, lub zwraca null
, jeśli ten zbiór jest pusty.
boolean remove(Object o): Usuwa określony element z tego zbioru, jeśli jest obecny.
int size(): Zwraca liczbę elementów w tym zbiorze (jego moc).
SpliteratorSpliterator
po elementach tego zbioru.
NavigableSet
SortedSet
SortedSet
NavigableSettrue
) fromElement.
Projekt W14, example28
package example28;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetExample {
public static void main(String[] args) {
// Tworzenie TreeSet
TreeSet<String> stringSet = new TreeSet<>();
TreeSet<Integer> intSet = new TreeSet<>();
// Dodawanie elementów
stringSet.add("Jabłko");
stringSet.add("Banana");
intSet.add(1);
intSet.add(2);
// Sprawdzanie, czy zbiór zawiera element
boolean containsBanana = stringSet.contains("Banana");
// Pobieranie pierwszego i ostatniego elementu
String firstString = stringSet.first();
Integer lastInt = intSet.last();
// Usuwanie elementów
stringSet.remove("Jabłko");
intSet.pollFirst();
// Pobieranie podzbioru
TreeSet<Integer> subSet = new TreeSet<>(intSet.subSet(1, true, 3, false));
// Iteracja przez zbiór
for(String s : stringSet) {
System.out.println(s);
}
// Czyszczenie zbioru
intSet.clear();
// Utworzenie TreeSet z odwróconym porównywaniem
TreeSet<String> reverseOrderSet = new TreeSet<>(Comparator.reverseOrder());
// Dodanie elementów do TreeSet
reverseOrderSet.add("Alfa");
reverseOrderSet.add("Bravo");
reverseOrderSet.add("Charlie");
reverseOrderSet.add("Delta");
// Wyświetlenie elementów w odwróconym porządku
System.out.println("Elementy TreeSet w odwróconym porządku:");
for(String element : reverseOrderSet) {
System.out.println(element);
}
}
}
HashMap
(mapa mieszająca)HashMap<K,V>
w Javie to kolekcja, która przechowuje pary klucz-wartość. Jest to część Java Collections Framework i oferuje efektywne sposoby przechowywania i dostępu do danych.
Struktura klucz-wartość: Każdy element w HashMap
składa się z klucza (unikalnego identyfikatora) i przypisanej mu wartości.
Szybki dostęp do danych: Dzięki funkcji mieszającej (hashing), HashMap
pozwala na bardzo szybkie wyszukiwanie wartości na podstawie klucza. Operacje takie jak wstawianie, wyszukiwanie lub usuwanie elementów mają zazwyczaj stałą złożoność czasową O(1).
Unikalność kluczy: W HashMap
każdy klucz musi być unikalny. Próba wstawienia duplikatu klucza spowoduje nadpisanie starej wartości przez nową.
Null jako klucz i wartość: HashMap
pozwala na użycie null
jako klucza (ale tylko raz, ponieważ klucze są unikalne) oraz null
jako wartości.
Nieuporządkowana: Kolejność przechowywania par klucz-wartość w HashMap
nie jest gwarantowana i może się zmieniać z czasem, zwłaszcza po operacjach, które zmieniają rozmiar mapy, np. po dodaniu nowych elementów.
Metody: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/HashMap.html
void clear(): Usuwa wszystkie mapowania z tej mapy.
Object clone(): Zwraca płytką kopię tej instancji HashMap
: klucze i wartości same w sobie nie są klonowane.
V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction): Próbuje obliczyć mapowanie dla określonego klucza i jego aktualnie mapowanej wartości (lub null
, jeśli mapowanie nie istnieje).
V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction): Jeśli określony klucz nie jest jeszcze skojarzony z wartością (lub jest mapowany na null
), próbuje obliczyć jego wartość za pomocą podanej funkcji mapującej i wprowadza ją do tej mapy, chyba że wynik jest null
.
V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction): Jeśli wartość dla określonego klucza jest obecna i nie jest null
, próbuje obliczyć nowe mapowanie na podstawie klucza i jego aktualnie mapowanej wartości.
boolean containsKey(Object key): Zwraca true
, jeśli ta mapa zawiera mapowanie dla określonego klucza.
boolean containsValue(Object value): Zwraca true
, jeśli ta mapa mapuje jeden lub więcej kluczy na określoną wartość.
Set<Map.Entry<K,V>> entrySet(): Zwraca widok zbioru mapowań zawartych w tej mapie.
V get(Object key): Zwraca wartość, do której mapowany jest określony klucz, lub null
, jeśli ta mapa nie zawiera mapowania dla klucza.
boolean isEmpty(): Zwraca true
, jeśli ta mapa nie zawiera żadnych mapowań klucz-wartość.
Set
V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction): Jeśli określony klucz nie jest już skojarzony z wartością lub jest skojarzony z null
, kojarzy go z podaną wartością niebędącą null
.
static <K,V> HashMap<K,V> newHashMap(int numMappings): Tworzy nową, pustą HashMap
odpowiednią dla oczekiwanej liczby mapowań.
V put(K key, V value): Kojarzy określoną wartość z określonym kluczem w tej mapie.
void putAll(Map<? extends K,? extends V> m): Kopiuje wszystkie mapowania z określonej mapy do tej mapy.
V remove(Object key): Usuwa mapowanie dla określonego klucza z tej mapy, jeśli jest obecne.
int size(): Zwraca liczbę mapowań klucz-wartość w tej mapie.
Collection
Projekt W14, example29
package example29;
import java.util.HashMap;
public class HashMapExample {
public static void main(String[] args) {
// Tworzenie HashMap
HashMap<String, Integer> fruitMap = new HashMap<>();
HashMap<Integer, String> reverseMap = new HashMap<>();
// Dodawanie elementów
fruitMap.put("Jabłko", 10);
fruitMap.put("Banana", 20);
reverseMap.put(1, "Jeden");
reverseMap.put(2, "Dwa");
// Pobieranie wartości
Integer appleCount = fruitMap.get("Jabłko");
String numberTwo = reverseMap.get(2);
// Sprawdzanie obecności klucza lub wartości
boolean hasBanana = fruitMap.containsKey("Banana");
boolean hasTwenty = reverseMap.containsValue("Dwa");
// Usuwanie elementu
fruitMap.remove("Banana");
// Iteracja przez mapę
for (String key : fruitMap.keySet()) {
System.out.println(key + " -> " + fruitMap.get(key));
}
// Pobieranie liczby elementów
int size = reverseMap.size();
// Czyszczenie mapy
reverseMap.clear();
}
}
Projekt W14, example30
package example30;
import java.util.HashMap;
import java.util.Map;
public class HashMapEntrySetExample {
public static void main(String[] args) {
// Pierwsza HashMap
HashMap<String, Integer> prices = new HashMap<>();
prices.put("Apple", 50);
prices.put("Orange", 30);
prices.put("Banana", 20);
// Druga HashMap
HashMap<Integer, String> daysOfWeek = new HashMap<>();
daysOfWeek.put(1, "Monday");
daysOfWeek.put(2, "Tuesday");
daysOfWeek.put(3, "Wednesday");
// Wyświetlanie używając entrySet() dla pierwszej mapy
for (Map.Entry<String, Integer> entry : prices.entrySet()) {
System.out.println(entry.getKey() + " costs " + entry.getValue());
}
// Wyświetlanie używając entrySet() dla drugiej mapy
for (Map.Entry<Integer, String> entry : daysOfWeek.entrySet()) {
System.out.println("Day " + entry.getKey() + " is " + entry.getValue());
}
}
}
TreeMap
(mapa drzewiasta)TreeMap<K,V>
w Javie to posortowana mapa bazująca na czerwono-czarnym drzewie. Jest to część Java Collections Framework i działa jako mapa klucz-wartość, gdzie każdy klucz jest unikalny.
Automatyczne sortowanie: Klucze w TreeMap
są sortowane według naturalnego porządku (jeśli implementują interfejs Comparable
) lub według Comparatora
przekazanego przy tworzeniu mapy. Dzięki temu, kiedy iterujesz po kluczach, są one zwracane w posortowanej kolejności.
Wykonanie: Operacje wyszukiwania, wstawiania i usuwania mają logarytmiczną złożoność czasową O(log n), co sprawia, że TreeMap
jest wydajna dla dużych zbiorów danych.
Null jako klucz: Standardowo TreeMap
nie akceptuje null
jako klucza (w przeciwieństwie do HashMap
), szczególnie gdy używa naturalnego porządkowania, ponieważ null
nie może być porównywany.
Dostęp do pierwszego i ostatniego elementu: TreeMap
zapewnia szybki dostęp do pierwszego (najmniejszego) i ostatniego (największego) klucza.
Widoki: TreeMap
oferuje metody takie jak headMap
, tailMap
i subMap
, które pozwalają na tworzenie widoków określonych zakresów mapy.
Metody: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/TreeMap.html
Map.Entry<K,V> ceilingEntry(K key): Zwraca mapowanie klucz-wartość związane z najmniejszym kluczem większym lub równym podanemu kluczowi, lub null
, jeśli taki klucz nie istnieje.
K ceilingKey(K key): Zwraca najmniejszy klucz większy lub równy podanemu kluczowi, lub null
, jeśli taki klucz nie istnieje.
void clear(): Usuwa wszystkie mapowania z tej mapy.
Object clone(): Zwraca płytką kopię tej instancji TreeMap
.
Comparator<? super K> comparator(): Zwraca komparator używany do porządkowania kluczy w tej mapie, lub null
, jeśli mapa używa naturalnego porządkowania swoich kluczy.
V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction): Próbuje obliczyć mapowanie dla określonego klucza i jego aktualnie mapowanej wartości (lub null
, jeśli mapowanie nie istnieje).
V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction): Jeśli określony klucz nie jest już skojarzony z wartością (lub jest mapowany na null
), próbuje obliczyć jego wartość za pomocą podanej funkcji mapującej i wprowadza ją do tej mapy, chyba że wynik jest null
.
V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction): Jeśli wartość dla określonego klucza jest obecna i nie jest null
, próbuje obliczyć nowe mapowanie na podstawie klucza i jego aktualnie mapowanej wartości.
boolean containsKey(Object key): Zwraca true
, jeśli ta mapa zawiera mapowanie dla określonego klucza.
boolean containsValue(Object value): Zwraca true
, jeśli ta mapa mapuje jeden lub więcej kluczy na określoną wartość.
NavigableSetNavigableSet
kluczy zawartych w tej mapie.
NavigableMap<K,V> descendingMap(): Zwraca widok w odwrotnej kolejności mapowań zawartych w tej mapie.
Set<Map.Entry<K,V>> entrySet(): Zwraca widok zbioru mapowań zawartych w tej mapie.
Map.Entry<K,V> firstEntry(): Zwraca mapowanie klucz-wartość związane z najmniejszym kluczem w tej mapie, lub null
, jeśli mapa jest pusta.
K firstKey(): Zwraca pierwszy (najniższy) klucz obecnie w tej mapie.
Map.Entry<K,V> floorEntry(K key): Zwraca mapowanie klucz-wartość związane z największym kluczem mniejszym lub równym podanemu kluczowi, lub null
, jeśli taki klucz nie istnieje.
K floorKey(K key): Zwraca największy klucz mniejszy lub równy podanemu kluczowi, lub null
, jeśli taki klucz nie istnieje.
V get(Object key): Zwraca wartość, do której mapowany jest określony klucz, lub null
, jeśli ta mapa nie zawiera mapowania dla klucza.
SortedMap<K,V> headMap(K toKey): Zwraca widok części tej mapy, której klucze są ściśle mniejsze niż toKey.
NavigableMap<K,V> headMap(K toKey, boolean inclusive): Zwraca widok części tej mapy, której klucze są mniejsze niż (lub równe, jeśli inclusive jest true
) toKey.
Map.Entry<K,V> higherEntry(K key): Zwraca map
owanie klucz-wartość związane z najmniejszym kluczem ściśle większym niż podany klucz, lub null
, jeśli taki klucz nie istnieje.
K higherKey(K key): Zwraca najmniejszy klucz ściśle większy niż podany klucz, lub null
, jeśli taki klucz nie istnieje.
Set
Map.Entry<K,V> lastEntry(): Zwraca mapowanie klucz-wartość związane z największym kluczem w tej mapie, lub null
, jeśli mapa jest pusta.
K lastKey(): Zwraca ostatni (najwyższy) klucz obecnie w tej mapie.
Map.Entry<K,V> lowerEntry(K key): Zwraca mapowanie klucz-wartość związane z największym kluczem ściśle mniejszym niż podany klucz, lub null
, jeśli taki klucz nie istnieje.
K lowerKey(K key): Zwraca największy klucz ściśle mniejszy niż podany klucz, lub null
, jeśli taki klucz nie istnieje.
V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction): Jeśli określony klucz nie jest już skojarzony z wartością lub jest skojarzony z null
, kojarzy go z podaną wartością niebędącą null
.
NavigableSetNavigableSet
kluczy zawartych w tej mapie.
Map.Entry<K,V> pollFirstEntry(): Usuwa i zwraca mapowanie klucz-wartość związane z najmniejszym kluczem w tej mapie, lub null
, jeśli mapa jest pusta.
Map.Entry<K,V> pollLastEntry(): Usuwa i zwraca mapowanie klucz-wartość związane z największym kluczem w tej mapie, lub null
, jeśli mapa jest pusta.
V put(K key, V value): Kojarzy określoną wartość z określonym kluczem w tej mapie.
void putAll(Map<? extends K,? extends V> map): Kopiuje wszystkie mapowania z określonej mapy do tej mapy.
V putFirst(K k, V v): Rzuca wyjątek UnsupportedOperationException
.
V putLast(K k, V v): Rzuca wyjątek UnsupportedOperationException
.
V remove(Object key): Usuwa mapowanie dla tego klucza z tej mapy TreeMap
, jeśli jest obecne.
int size(): Zwraca liczbę mapowań klucz-wartość w tej mapie.
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive): Zwraca widok części tej mapy, której klucze mieszczą się w zakresie od fromKey do toKey.
SortedMap<K,V> subMap(K fromKey, K toKey): Zwraca widok części tej mapy, której klucze mieszczą się w zakresie od fromKey, włącznie, do toKey, wyłącznie.
SortedMap<K,V> tailMap(K fromKey): Zwraca widok części tej mapy, której klucze są większe lub równe fromKey.
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive): Zwraca widok części tej mapy, której klucze są większe niż (lub równe, jeśli inclusive jest true
) fromKey.
Collection
Projekt W14, example31
package example31;
import java.util.Comparator;
import java.util.TreeMap;
public class TreeMapExample {
public static void main(String[] args) {
// Tworzenie TreeMap
TreeMap<String, Integer> fruitMap = new TreeMap<>();
TreeMap<Integer, String> reverseMap = new TreeMap<>();
// Dodawanie elementów
fruitMap.put("Jabłko", 50);
fruitMap.put("Banana", 20);
fruitMap.put("Pomarańcza", 30);
reverseMap.put(1, "Poniedziałek");
reverseMap.put(2, "Wtorek");
reverseMap.put(3, "Środa");
// Pobieranie pierwszego i ostatniego klucza
String firstKey = fruitMap.firstKey();
Integer lastKey = reverseMap.lastKey();
// Sprawdzanie obecności klucza
boolean hasApple = fruitMap.containsKey("Jabłko");
// Usuwanie elementu
fruitMap.remove("Banana");
// Pobieranie i ustawianie wartości
Integer appleCount = fruitMap.get("Jabłko");
reverseMap.put(3, "Środa");
// Iteracja przez mapę
for (String key : fruitMap.keySet()) {
System.out.println(key + " -> " + fruitMap.get(key));
}
// Pobieranie podmapy
TreeMap<String, Integer> subMap = new TreeMap<>(fruitMap.subMap("Jabłko", true, "Pomarańcza", true));
// Czyszczenie mapy
reverseMap.clear();
// Utworzenie TreeMap z odwróconym porównywaniem dla kluczy
TreeMap<String, Double> reverseOrderMap = new TreeMap<>(Comparator.reverseOrder());
// Dodanie elementów do TreeMap
reverseOrderMap.put("Alfa", 1.5);
reverseOrderMap.put("Bravo", 2.5);
reverseOrderMap.put("Charlie", 3.5);
reverseOrderMap.put("Delta", 4.5);
// Wyświetlenie elementów w odwróconym porządku kluczy
System.out.println("Elementy TreeMap w odwróconym porządku kluczy:");
reverseOrderMap.forEach((key, value) -> System.out.println(key + ": " + value));
}
}
Projekt W14, example32
package example32;
import java.util.Map;
import java.util.TreeMap;
public class TreeMapExample32 {
public static void main(String[] args) {
TreeMap<String, Double> prices = new TreeMap<>();
// Dodawanie par klucz-wartość
prices.put("Apple", 1.99);
prices.put("Banana", 0.49);
prices.put("Cherry", 2.99);
prices.put("Date", 3.49);
prices.put("Elderberry", 1.79);
prices.put("Fig", 2.09);
// Użycie metody ceilingEntry
Map.Entry<String, Double> ceiling = prices.ceilingEntry("Cantaloupe");
// Użycie metody firstEntry
Map.Entry<String, Double> first = prices.firstEntry();
// Użycie metody higherEntry
Map.Entry<String, Double> higher = prices.higherEntry("Cherry");
// Użycie metody lowerEntry
Map.Entry<String, Double> lower = prices.lowerEntry("Date");
// Wyświetlanie wyników
System.out.println("Ceiling Entry: " + ceiling.getKey() + " -> " + ceiling.getValue());
System.out.println("First Entry: " + first.getKey() + " -> " + first.getValue());
System.out.println("Higher Entry: " + higher.getKey() + " -> " + higher.getValue());
System.out.println("Lower Entry: " + lower.getKey() + " -> " + lower.getValue());
}
}
Collections
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Collections.html
Klasa Collections
w Javie pełni rolę narzędzia pomocniczego (utility class) dla kolekcji w Java Collections Framework. Zawiera ona statyczne metody, które działają na lub zwracają kolekcje. Jest to klasa czysto statyczna, co oznacza, że nie jest przeznaczona do tworzenia instancji (obiektów), lecz służy jako zbiór narzędzi dla różnych operacji na kolekcjach.
Napisz statyczną metodę printUnique(Iterator<T> items)
, która przyjmuje generyczny interfejs Iterator
jako argument i wyświetla na ekranie każdy unikalny element dokładnie raz.
Projekt W14, example33
Napisz statyczną metodę printUnique(Collection<T> items)
, która przyjmuje generyczny interfejs Collection jako argument i wyświetla na ekranie każdy unikalny element z tej kolekcji dokładnie raz.
Projekt W14, example34
Napisz statyczną metodę findCommonElements
, która przyjmuje dwie generyczne listy powiązane (LinkedList<T> list1
i LinkedList<T> list2
) i zwraca nową listę zawierającą elementy, które występują zarówno w list1
, jak i list2
. Elementy w zwróconej liście powinny być unikalne i nie muszą być posortowane. Metoda nie powinna modyfikować wejściowych list.
Napisz statyczną metodę hasCommonElements
, która przyjmuje dwa generyczne zbiory (HashSet<T> set1
i HashSet<T> set2
) i zwraca true
, jeśli oba zbiory mają przynajmniej jeden wspólny element, oraz false
w przeciwnym przypadku.
Napisz metodę findElementsInRange
, która przyjmuje TreeSet<T>
oraz dwie wartości graniczne T lowerBound
i T upperBound
. Metoda powinna zwracać TreeSet<T>
, który zawiera wszystkie elementy z pierwotnego zbioru, które mieszczą się w przedziale między lowerBound
a upperBound
(włącznie z obiema granicami).
Napisz metodę countValueOccurrences
, która przyjmuje generyczną HashMap (HashMap<K, V> map
) i zwraca nową HashMap (HashMap<V, Integer>
), gdzie każdy klucz to wartość z oryginalnej mapy, a wartość to liczba wystąpień tej wartości w oryginalnej mapie.
Napisz metodę subMapInRange
, która przyjmuje generyczną TreeMap (TreeMap<K, V> map
), a także dwie wartości kluczy K startKey
i K endKey
. Metoda powinna zwrócić nową TreeMap, która zawiera wszystkie pary klucz-wartość z oryginalnej mapy, których klucze mieszczą się w zakresie od startKey
do endKey
, włącznie.