Interfejs Set - Zbiory
Set jest interfejsem wchodzącym w skład Collections Framework Javy. Reprezentuje on kolekcję unikalnych elementów, ale nie wspomina nic o kolejności ich przechowywania, ponieważ ta zależy już od konkretnej jego implementacji. Set jest typem generycznym, co oznacza, że możemy określić elementy jakiego typu będziemy w nim przechowywali, a to pozwoli nam uniknąć konieczności rzutowania.
Implementacje
Wśród dostępnych implementacji zbiorów możemy wyróżnić ich trzy rodzaje:
- HashSet - podstawowa implementacja, zapewnia unikalność elementów, ale nie mamy żadnej gwarancji co do ich kolejności. Wewnętrznie wykorzystywana jest tablica mieszająca, co wymaga poprawnej implementacji metod hashCode() oraz equals().
- TreeSet - implementacja oparta o drzewa czerwono czarne, która oprócz unikalności elementów gwarantuje nam uporządkowanie wstawianych elementów zgodnie z naturalnym porządkiem. Porządek ten wyznaczany jest poprzez implementację interfejsu Comparable lub zastosowanie odpowiedniego Comparatora.
- LinkedHashSet - implementacja wykorzystująca wewnętrznie zarówno tablicę mieszającą jak i dodatkową listę podwójnie wiązaną, dzięki czemu oprócz unikalności elementów zagwarantowana jest także kolejność elementów zgodna z tą w jakiej były one dodawane
Różnica między HashSet, TreeSet i LinkedHashSet
HashSet jest podstawową implementacją, która zapewnia jedynie unikalność elementów, TreeSet gwarantuje dodatkowe sortowanie, a LinkedHashSet pamięta dodatkowo kolejnoś wstawiania.
Wybór odpowiedniej implementacji zależy przede wszystkim od naszych potrzeb. Wszystkie zbiory są strukturami wydajnymi, ponieważ opierają się albo o tablice mieszające lub struktury drzewiaste, a to zapewnia stałą lub logarytmiczną złożoność obliczeniową.
Dostępne metody
Najważniejsze metody w interfejsie Set to odziedziczone z interfejsu Collection:
- boolean add(E e) - dodaje unikalny element do zbioru, w przypadku, gdy element się powtarza dodawanie jest ignorowane. Unikalność jest sprawdzana na podstawie metod hashCode() i equals(). Do zbioru można dodać jedną wartość null
- boolean contains(Object o) - sprawdza, czy obiekt 'o' znajduje się w zbiorze
- boolean isEmpty() - sprawdza, czy zbiór jest pusty
- Iterator iterator() - zwraca iterator. Kolejność elementów jest zależna od tego z jakiej implementacji korzystamy
- boolean remove(Object o) - usuwa element 'o' ze zbioru
- int size() - zwraca rozmiar (ilość elementów) zbioru
Dodatkowo w poszczególnych implementacjach znajdziemy dodatkowe metody, przykładowo w TreeSet znajdziemy metodę first() , która zwraca "najmniejszy" obiekt w rozumieniu naturalnego porządku, oraz last() , która zwraca największy z nich. Więcej znajdziesz w dokumentacji.
Przykład
Jako przykład napiszmy program, w którym stworzymy zbiór typu TreeSet (posortowany) z imionami. Spróbujmy dodać kilka duplikatów, a następnie wyświetlmy wynik działania kilku metod.
import java.util.Set;
import java.util.TreeSet;
public class SetExample {
public static void main(String[] args) {
Set<String> names = new TreeSet<>();
names.add("Kasia");
names.add("Ania");
names.add("Ania");
names.add("Wojtek");
names.add("Zuza");
names.add("Zuza");
int setSize = names.size();
System.out.println("Number of names: " + setSize);
boolean isThereAnia = names.contains("Ania");
System.out.println("Is Ania in this set? " + isThereAnia);
for(String name: names) {
System.out.println(name);
}
}
}
Stworzyliśmy zbiór typu TreeSet i przypisaliśmy go do zmiennej typu Set. W przypadku wszystkich rodzajów kolekcji dobrze jest się posługiwać referencją ogólnego typu, ponieważ możemy w takiej sytuacji podmienić TreeSet np. na LinkedHashSet w dowolnym momencie, bez konieczności zmiany reszty kodu, jest to oczywiście zasługa polimorfizmu.
Do zbioru próbujemy dodać kilka imion w tym duplikaty Ani oraz Zuzy. Ponieważ zbiór oczekuje elementów unikalnych, to wystąpią one tylko raz. Dodatkowo przy wyświetlaniu zauważymy, że elementy są posortowane, ponieważ klasa String implementuje interfejs Comparable.
Dyskusja i komentarze
Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.