26 Kolekcje
26.1 Interfejs Collection
A1. 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.
A2. Stwórz statyczną metodę countOccurrences(Collection<T> items, T element)
, która zwraca liczbę wystąpień danego elementu w podanej kolekcji. Funkcja powinna działać dla dowolnego typu obiektów przechowywanych w kolekcji.
A3. Zaimplementuj metodę removeEveryOther(Collection<T> items)
, która usuwa co drugi element z przekazanej kolekcji. Metoda powinna modyfikować oryginalną kolekcję, nie tworząc jej kopii.
26.2 Interfejs Iterable
B1. Napisz metodę reversePrint(Iterable items)
, która przyjmuje generyczny interfejs Iterable jako argument i wyświetla na ekranie elementy tej sekwencji w odwrotnej kolejności, niż zostały one przekazane.
B2. Stwórz funkcję findMax(Iterable numbers)
, która przeszukuje kolekcję typu Iterable zawierającą liczby i zwraca największą liczbę. Zakładamy, że elementy kolekcji są obiektami klasy Comparable
.
B3. Zaimplementuj metodę countElements(Iterable items, Object element)
, która zlicza ile razy dany element pojawił się w kolekcji implementującej interfejs Iterable. Metoda powinna porównywać elementy przy użyciu metody equals
.
26.3 Lista tablicowa ArrayList
C1. Stwórz metodę mergeLists
, która przyjmuje dwie generyczne ArrayList<T>
i zwraca nową ArrayList<T>
, będącą połączeniem elementów z obu list. Upewnij się, że kolejność elementów z oryginalnych list jest zachowana w wynikowej liście.
C2. Napisz funkcję removeDuplicates
, która przyjmuje ArrayList<T>
i zwraca nową listę, z której usunięto wszystkie duplikaty, pozostawiając tylko unikalne elementy. Kolejność zachowanych elementów powinna odpowiadać ich pierwszemu wystąpieniu na oryginalnej liście.
C3. Zaimplementuj metodę countOccurrences
, która przyjmuje ArrayList<T>
i element typu T
, a następnie zwraca liczbę wystąpień tego elementu w podanej liście.
26.4 Lista powiązana LinkedList
D1. Napisz metodę isPalindrome
, która przyjmuje generyczną listę powiązaną (LinkedList<T> list
) i zwraca true
, jeśli lista jest palindromem, a false
w przeciwnym przypadku. Lista jest palindromem, gdy czytana od przodu i od tyłu jest taka sama. Metoda powinna być jak najbardziej wydajna.
D2. Napisz 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.
26.5 Zbiór bazujący na tablicy skrótów HashSet
E1. Napisz metodę findUniqueElements
, która przyjmuje generyczną listę (List<T> list
) i zwraca HashSet<T>
, który zawiera tylko unikalne elementy z tej listy. Metoda powinna skutecznie eliminować duplikaty.
E2. Napisz 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.
E3. Napisz metodę unionSets
, która przyjmuje dwie generyczne kolekcje typu HashSet<T>
(HashSet<T> set1
i HashSet<T> set2
) i zwraca nowy zbiór (HashSet<T>
), który jest zbiorem unii obu wejściowych zbiorów. Wynikowy zbiór powinien zawierać wszystkie elementy, które występują w set1
, set2
, lub w obu tych zbiorach.
26.6 TreeSet
F1. 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).
F2. Napisz metodę removeMinMax
, która przyjmuje TreeSet<T>
i modyfikuje go przez usunięcie najmniejszego i największego elementu. Metoda powinna zwracać parę (np. klasę Pair
lub dwuelementową tablicę/listę) zawierającą usunięte wartości. Jeśli zbiór ma mniej niż dwa elementy, metoda powinna zwrócić odpowiednie wartości nullowe lub wskazywać na błąd.
F3. Napisz metodę findClosestElement
, która przyjmuje TreeSet<T>
i wartość T target
. Metoda powinna zwracać element zbioru, który jest najbliżej wartości target
. W przypadku, gdy dwa elementy są równie blisko, metoda może zwrócić dowolny z nich. Zakładamy, że typ T
pozwala na porównywanie wartości (np. poprzez implementację interfejsu Comparable<T>
).
26.7 Queue
G1. Napisz metodę reverseQueue
, która przyjmuje generyczną kolejkę (Queue<T> queue
) i odwraca kolejność jej elementów. Metoda powinna wykonywać operacje odwracania w miejscu, nie używając dodatkowych kolekcji.
G2. Napisz metodę simulateSupermarketQueue
, która przyjmuje generyczną kolejkę (Queue<Customer> customers
) i dodatnią liczbę całkowitą n
, reprezentujący liczbę dostępnych kas. Klasa Customer
zawiera czas obsługi klienta. Metoda powinna zwrócić całkowity czas potrzebny do obsłużenia wszystkich klientów w kolejce, przy założeniu, że każda kasa obsługuje jednego klienta na raz i wybiera następnego klienta z przodu kolejki, gdy tylko zostanie zwolniona.
26.8 Deque
H1. Napisz metodę isSymmetric
, która przyjmuje generyczny Deque (Deque<T> deque
) i zwraca true
, jeśli elementy w Deque są ułożone symetrycznie (tj. kolejność elementów jest taka sama, gdy czytamy je od przodu do tyłu i od tyłu do przodu). W przeciwnym przypadku metoda zwraca false
.
H2. Napisz metodę removeEverySecondElement
, która przyjmuje generyczny Deque (Deque<T> deque
) i usuwa z niego co drugi element, zaczynając od drugiego elementu w kolejności, w której elementy zostały dodane. Metoda powinna modyfikować oryginalny Deque, nie zwracając nic.
H3. Napisz metodę swapEnds
, która przyjmuje generyczny Deque (Deque<T> deque
) i zamienia miejscami pierwszy element z ostatnim. Jeśli Deque zawiera mniej niż dwa elementy, metoda nie powinna nic robić. Metoda powinna modyfikować oryginalny Deque, nie zwracając nic.
26.9 Kolejka priorytetowa PriorityQueue
I1. Napisz metodę mergePriorityQueues
, która przyjmuje dwie generyczne PriorityQueues (PriorityQueue<T> queue1
i PriorityQueue<T> queue2
). Metoda powinna zwrócić nową PriorityQueue zawierającą wszystkie elementy z obu wejściowych kolejek. Zakładamy, że elementy w obu kolejnych mogą być porównywane między sobą.
26.10 Map
J1. Napisz metodę reverseMap
, która przyjmuje generyczną mapę (Map<K, V> map
) i zwraca nową mapę (Map<V, K>
), gdzie każdy klucz staje się wartością, a każda wartość kluczem. Jeśli oryginalna mapa zawiera powtarzające się wartości, zachowaj tylko ostatnią parę klucz-wartość odwracając mapę.
J2. Napisz metodę findKeysWithMaxValue
, która przyjmuje generyczną mapę (Map<K, V> map
), gdzie wartości są porównywalne (implementują Comparable<V>
). Metoda powinna zwracać listę wszystkich kluczy, które są powiązane z największą wartością w mapie.
J3. Napisz metodę groupByValue
, która przyjmuje generyczną mapę (Map<K, V> map
) i zwraca nową mapę (Map<V, List<K>>
), gdzie każda wartość z oryginalnej mapy staje się kluczem w nowej mapie, a jej wartością jest lista kluczy, które były z nią powiązane w oryginalnej mapie.
26.11 HashMap
K1. 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.
K2. Napisz metodę swapKeysAndValues
, która przyjmuje generyczną HashMap (HashMap<K, V> map
) i zwraca nową HashMap (HashMap<V, K>
), gdzie każdy klucz z oryginalnej mapy staje się wartością, a każda wartość kluczem. Zakładamy, że wszystkie wartości w oryginalnej mapie są unikalne.
K3. Napisz metodę aggregateValuesByKey
, która przyjmuje generyczną HashMap (HashMap<K, Integer> map
) oraz klucz (K key
) i wartość (Integer value
). Metoda powinna dodać wartość do obecnej wartości skojarzonej z kluczem. Jeśli klucz nie istnieje w mapie, powinien zostać dodany z podaną wartością. Metoda nie zwraca nic, modyfikując oryginalną mapę.
K4. Napisz metodę compareMaps
, która przyjmuje dwie generyczne HashMap (HashMap<K, V> map1
i HashMap<K, V> map2
) i zwraca true
, jeśli obie mapy mają dokładnie te same pary klucz-wartość, oraz false
w przeciwnym przypadku. Metoda powinna porównywać zarówno klucze, jak i wartości.
26.12 TreeMap
L1. 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.
L2. Napisz metodę reverseOrderMap
, która przyjmuje generyczną TreeMap (TreeMap<K, V> map
). Metoda powinna zwrócić nową TreeMap, która zawiera wszystkie pary klucz-wartość z oryginalnej mapy, ale z odwróconą kolejnością kluczy.
Wskazówka: wykorzystaj Collections.reverseOrder()
.
L3. Napisz metodę calculateAverageValue
, która przyjmuje generyczną TreeMap (TreeMap<K, Double> map
). Metoda powinna obliczać i zwracać średnią wartość wszystkich wartości (typu Double) przechowywanych w mapie. Zakładamy, że mapa nie jest pusta.
26.13 Vector
M1. Stwórz funkcję concatenateVectors
, która przyjmuje dwa obiekty Vector<T>
i zwraca nowy Vector<T>
, zawierający wszystkie elementy z pierwszego wektora, a po nich wszystkie elementy z drugiego wektora.
M2. Napisz metodę reverseVector
, która przyjmuje obiekt Vector<T>
i zwraca nowy Vector<T>
, w którym kolejność elementów jest odwrócona względem oryginalnego wektora.
M3. Zaimplementuj funkcję filterVector
, która przyjmuje Vector<T>
i interfejs funkcyjny Predicate<T>
. Funkcja powinna zwracać nowy Vector<T>
, zawierający tylko te elementy z oryginalnego wektora, które spełniają warunek zdefiniowany przez Predicate<T>
.