Następna porcja wiedzy na temat kolekcji w Javie. Wcześniej poruszyłem temat kolekcji "TreeSet", a teraz dowiemy się co nieco o bardzo podobnej kolekcji zwanej "HashSet". Przy okazji będzie wstęp do rozumienia "równości" obiektów. Zapraszam po szczegóły.

HASHSET W JAVIE. WYJAŚNIENIE SENSU ZBIORU

W poprzednim artykule wspomniałem powierzchownie o zbiorach i jaki jest sens ich wykorzystywania. Zbiór jest kolekcją, która ma za zadanie "pilnować", aby nie został dodany jakikolwiek duplikat. Byliśmy wtedy świadkami jak "TreeSet" nie spełniał tej cechy i wystarczyło podać tylko inny rok nawet z tymi samymi danymi, aby książka "weszła" do kolekcji. Obie kolekcje są ze sobą powiązane i to dosłownie, bo implementują ten sam interfejs jakim jest "Set". Jednak "HashSet" w przeciwieństwie do "TreeSet", nie zajmuje się sortowaniem i to nie jest jego "natura". On ma za zadanie jedynie przechowywanie samych unikatowych elementów.

"RÓWNOŚĆ" OBIEKTÓW. ROZUMIENIE USTALANIA IDENTYCZNOŚCI

Przytoczmy raz kolejny przykład z książką jednak zamieniając kolekcję na "HashSet". Najpierw sobie skopiujcie te kody źródłowe, potem skompilujcie i uruchomcie program:

  • KLASA "Main"
public class Main
{
	public static void main(String[] args)
	{
		new Launcher();
	}
}
  • KLASA "Book"
public class Book
{
	private final String title, author, publisher;
	private final int year;

	public Book(String author, String title, String publisher, int year)
	{
		this.author = author;
		this.title = title;
		this.publisher = publisher;
		this.year = year;
	}

	@Override
	public String toString()
	{
		return author + ". " + title + ". " + publisher + ", " + year;
	}
}
  • KLASA "Launcher"
import java. util.HashSet;

public class Launcher
{
	private HashSet<Book> books;

	public Launcher()
	{
		createInstances();
		addBooks();
		printBooks();
	}

	private void createInstances()
	{
		books = new HashSet<>();
	}

	private void addBooks()
	{
		books.add(new Book("Adam Mickiewicz", "Pan Tadeusz", "Aleksander Jełowicki", 1834));
		books.add(new Book("Gustaw Herling-Grudziński", "Inny świat", "Roy", 1951));
		books.add(new Book("Aleksander Głowacki", "Lalka", "Gebethner i Wolff", 1890));
		books.add(new Book("Adam Mickiewicz", "Pan Tadeusz", "Aleksander Jełowicki", 1834));
	}

	private void printBooks()
	{
		System.out.println("WYPISYWANIE KOLEKCJI:");
		books.forEach(System.out::println);
	}
}

Po uruchomieniu programu, ujrzycie cztery książki z czego jedna się powtórzy nawet bez zmiany jakiegokolwiek parametru! To wyraźny sygnał, że "HashSet" nie spełnia swojej roli w należyty sposób. Doświadczacie właśnie problemu związanego z ustalaniem kiedy dwa obiekty są sobie "równe". Dzielą się na dwa rodzaje: równość odwołań i równość obiektów.

Równość odwołań polega na weryfikacji tożsamości obu instancji czy ich adresy referencji się ze sobą pokrywają. Możemy dowieść, że dwa obiekty są sobie równe na podstawie ich odwołań tworząc jeden obiekt w jednej zmiennej i przypisując TEN SAM obiekt do drugiej zmiennej. "Kodowo" wyglądałoby to tak:

Integer integerA = new Integer(52);
Integer integerB = integerA;

System.out.println(integerA.equals(integerB));

Dodawanie do "HashSet" kolejnych elementów wymaga zastosowania tego drugiego rodzaju, równości obiektów. Sytuacja weryfikowania czy oba obiekty posiadają identyczną wartość jakiejś danej składowej (albo wielu). Dla naszej książki powinien to być tytuł, a najlepiej ISBN, ale nie wchodźmy w takie szczegóły. Można byłoby pokusić się o spostrzeżenie, że mogą być dwie książki o tym samym tytule, ale mieć inny numer wydania. Jak widzicie, jest kilka wariantów.

Równość obiektów w kolekcji "HashSet"

"HashSet" należy do kolekcji typu "zbiór" i jego podstawowym zadaniem jest zapewnienie, żeby żaden nowo wstawiany element nie był duplikatem już istniejącego. Kluczową sprawą jest logiczne zdefiniowanie "równości obiektów".


Dalsza część o równości obu obiektów dla kolekcji "HashSet" została zawarta w tym artykule, bo trzeba rozdzielić teorię od praktyki. Bywajcie!

PODOBNE ARTYKUŁY