Programowanie obiektowe

Wykład 15

Kolekcje

Przykład

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 W15, example33

package example33;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;

public class UniquePrinter {

    public static void main(String[] args) {
        ArrayList<String> names = new ArrayList<>();
        names.add("John");
        names.add("Jane");
        names.add("John");
        names.add("John");
        printUnique(names.iterator());
    }

    public static <T> void printUnique(Iterator<T> items) {
        HashSet<T> uniqueItems = new HashSet<>();

        while (items.hasNext()) {
            T item = items.next();
            if (uniqueItems.add(item)) {
                System.out.println(item);
            }
        }
    }
}

Przykład

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 W15, example34

package example34;

import java.util.ArrayList;
import java.util.Collection;

public class UniquePrinter {

    public static void main(String[] args) {
        ArrayList<Double> list = new ArrayList<>();
        list.add(1.0);
        list.add(2.0);
        list.add(1.0);
        list.add(1.0);
        printUnique(list);
    }

    public static <T> void printUnique(Collection<T> items) {
        HashSet<T> temp = new HashSet<>(items);
        System.out.println(temp);
    }
}

Przykład

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.

Projekt W15, example35

package example35;

import java.util.LinkedList;

public class Test35 {

    public static void main(String[] args) {
        LinkedList<String> list1 = new LinkedList<>();
        list1.add("John");
        list1.add("Sue");
        LinkedList<String> list2 = new LinkedList<>();
        list2.add("John");
        list2.add("Jane");
        list2.add("Adam");
        LinkedList<String> commonElements = findCommonElements(list1, list2);
        System.out.println(commonElements);

    }

    public static <T> LinkedList<T> findCommonElements(LinkedList<T> list1, LinkedList<T> list2) {
        LinkedList<T> commonElements = new LinkedList<>();
        for (T item : list1) {
            if (list2.contains(item) && !commonElements.contains(item)) {
                commonElements.add(item);
            }
        }
        return commonElements;
    }
}

Przykład

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.

Projekt W15, example36

package example36;

import java.util.HashSet;

public class Test36 {

    public static void main(String[] args) {
        HashSet<Integer> set1 = new HashSet<>();
        set1.add(1);
        set1.add(2);
        set1.add(3);
        HashSet<Integer> set2 = new HashSet<>();
        set2.add(4);
        set2.add(2);
        System.out.println(hasCommonElements(set1, set2));
    }

    public static <T> boolean hasCommonElements(HashSet<T> set1, HashSet<T> set2) {
        for (T element : set1) {
            if (set2.contains(element)) {
                return true;
            }
        }
        return false;
    }
}

Przykład

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).

Projekt W15, example37

package example37;

import java.util.TreeSet;

public class Alg {

    public <T extends Comparable<T>> TreeSet<T> findElementsInRange(TreeSet<T> treeSet, T lowerBound, T upperBound) {
        TreeSet<T> result = new TreeSet<>();
        for (T element : treeSet) {
            if (element.compareTo(lowerBound) >= 0 && element.compareTo(upperBound) <= 0) {
                result.add(element);
            }
        }
        return result;
    }
}
package example37;

import java.util.TreeSet;

public class Test37 {

    public static void main(String[] args) {
        Alg a1 = new Alg();
        TreeSet<Integer> treeSet = new TreeSet<>();
        treeSet.add(1);
        treeSet.add(2);
        treeSet.add(33);
        treeSet.add(4);
        treeSet.add(-5);
        System.out.println(treeSet);
        System.out.println(a1.findElementsInRange(treeSet, 1, 5));
    }

}

Przykład

Napisz statyczną 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.

Projekt W15, example38

package example38;

import java.util.HashMap;

public class Test38 {

    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();
        map.put("a", 1);
        map.put("b", 2);
        map.put("c", 1);
        map.put("d", 2);
        map.put("e", 1);
        System.out.println(map);
        System.out.println(countValueOccurrences(map));
    }

    public static <K, V> HashMap<V, Integer> countValueOccurrences(HashMap<K, V> map) {
        HashMap<V, Integer> result = new HashMap<>();
        for (V value : map.values()) {
            int count = 0;
            for (V value2 : map.values()) {
                if (value.equals(value2)) {
                    count++;
                }
            }
            result.put(value, count);
        }
        return result;
    }
}

Przykład

Napisz statyczną 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.

Projekt W15, example39

package example39;

import java.util.Map;
import java.util.TreeMap;

public class Test39 {

    public static void main(String[] args) {
        TreeMap<String, Integer> map = new TreeMap<>();
        map.put("a", 1);
        map.put("b", 2);
        map.put("c", 1);
        map.put("d", 2);
        map.put("e", 1);
        System.out.println(map);
        System.out.println(subMapInRange(map, "b", "d"));
    }

    public static <K extends Comparable<? super K>, V> TreeMap<K, V> subMapInRange(TreeMap<K, V> map, K startKey, K endKey) {
        TreeMap<K, V> result = new TreeMap<>();
        for (Map.Entry<K, V> entry : map.entrySet()) {
            K key = entry.getKey();
            if (key.compareTo(startKey) >= 0 && key.compareTo(endKey) <= 0) {
                result.put(key, entry.getValue());
            }
        }
        return result;
    }
}

Co dalej?

Co dalej?