Szkolenia programowania we Wrocławiu
Kurs Java Podstawy - rozszerzony

JavaTraps 003 - odpowiedź

Pytanie w tej części JavaTraps dotyczyło tego jaki rozmiar zbioru (HashSet) zostanie wyświetlony na ekranie, gdy dodamy do niego cztery obiekty typu URL. Przypomnijmy kod:

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;

public class JavaStart {

	public static void main(String[] args) throws MalformedURLException {
		Set set = new HashSet();
		set.add(new URL("http://wolnifarmerzy.com.pl"));
		set.add(new URL("http://zagubionawyspa.com.pl"));
		set.add(new URL("http://editor.javastart.pl"));
		set.add(new URL("http://google.pl"));

		System.out.println("Size: "+set.size());
	}
}

Na pierwszy rzut oka odpowiedź wydaje się oczywista. Metoda add powoduje dodanie nowego obiektu do kolekcji (wewnętrznie reprezentowanej jako tablica haszowana), po wcześniejszym sprawdzeniu, czy identyczny obiekt już nie istnieje. Warunek ten zostaje sprawdzony przy pomocy metody equals().

Poprawna odpowiedź to: D) inna odpowiedź

Niestety jest to spowodowane kiepskim rozwiązaniem w metodzie equals() klasy URL. Była ona projektowana, gdy internet był tak naprawdę jeszcze słabiej rozwinięty i nikt nie przypuszczał, że będzie taka sytuacja, w której na jednym serwerze o jednym IP będzie hostowanych kilka(naście) serwisów o takim samym adresie IP(wtedy jeszcze tylko v4). Metoda equals() traktuje dwa obiekty URL za równe, jeśli ich adres sieciowy się zgadza. Ponieważ strony wolnifarmerzy.com.pl oraz zagubionawyspa.com.pl posiadają taki sam adres IP serwera, to są przez metodą equals() traktowane jako równe obiekty, więc w wyniku otrzymamy Size: 3.

Nie jest to niestety jedyna prawidłowa odpowiedź. W przypadku, gdy nie będziemy połączeni z internetem, wynikiem będzie Size: 4 - nie zostanie wtedy porównany adres IP.

Niestety jest to spora niespójność, ponieważ wynik działania tej metody powinien być niezależny od platformy na jakiej zostanie wywołana.

Jak sobie z tym radzić?

Jeśli na prawdę nie masz rozsądnego wytłumaczenia do użycia klasy URL, zastąp ją nowszą klasą URI, w której podobne problemy nie występują. Udostępnia ona również metodę toURL(), więc tak naprawdę, nie ma rozsądnego wytłumaczenia do używania klasy URL w nowo pisanych programach.

Komentarze

Komentarze zamknięte. Zapraszamy do grupy na Facebooku
Pablo

sprawdzilem na Java 7 i przy polaczeniu z netem pokazuje 4, czyli prawidlowo. Prawdopodobnie nowa wersja poprawila braki:)

Sławek Ludwiczak

Java nie poprawiła braków, po prostu druga ze stron nie istnieje i nie jest pobierany jej adres IP