HashMap - dlaczego taki wynik ?

HashMap - dlaczego taki wynik ?
TI
  • Rejestracja:ponad 13 lat
  • Ostatnio:ponad 5 lat
  • Postów:65
0

Witam,
właśnie jestem po rozmowie rekrutacyjnej na której byłem bardzo mocno pytany o porównywanie obiektów, zawartość stringów itp
I teraz robię sobie testy i mam coś takiego jak poniżej. Czy jest ktoś wstanie wytłumaczyć mi dlaczego java System.out.println(map.get(s2)); wypisuje "cos"

Kopiuj
public class Main {

    public static void main(String[] args) {
        String s1 = "test";
        String s2 = "test";

        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));

        HashMap<String, String> map = new HashMap<>();
        map.put(s1,"cos");
        System.out.println(map.get(s2));

    }
}

V-2
  • Rejestracja:około 8 lat
  • Ostatnio:10 miesięcy
  • Postów:671
0

Taki sam string będzie miał taki sam hashcode, a jak sama nazwa każe się domyślać, HashMap opiera się na haszkodach właśnie


Nie ma najmniejszego powodu, aby w CV pisać "email" przed swoim adresem mailowym, "imię i nazwisko" przed imieniem i nazwiskiem, ani "zdjęcie mojej głowy od przedniej strony" obok ewentualnego zdjęcia. W drugiej firmie której już pracuję mam palących marihuanę programistów [...] piszą kod "leniwie", często nie wysilając się, rozwlekając ten kod, unikając np. programowania funkcyjnego (mówię tutaj o lambdach w javie).
Zobacz pozostałe 3 komentarze
katelx
mam nadzieje ze z racji szybkiego przyznania sie do winy kara bedzie stosownie mniejsza
krzysiek050
Za próbę ukrycia dowodów? Interpol już postawiony w stanie gotowości.
katelx
ok, w takim razie chyba lepiej zapadne sie pod ziemie
caer
nie tyle hashcode co to jest po prostu ten sam obiekt
czysteskarpety
czysteskarpety
@katelx znowu kręci? nie jestem zdziwiony, znam ją z innej sprawy i radzę uważać na tego allegrowicza (wystawiam negatywny)
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
2

A co by miało wypisać? o_O Skoro stringi są sobie równe to przecież oczywiste jest że możesz wybierać klucze z mapy za pomocą dowolnego z nich. Jaki to by miało sens inaczej? Co więcej String w Javie jest immutable i ma internal cache, wiec nie dość że stringi będą equal to najpewniej == też zwróci true, bo w rzeczywistości masz jednego stringa i dwie referencje do niego.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
V-2
Gdyby to były jakieś długie stringi (nie scache'owane), po referencji mogłyby być uznane za różne, ale hashcode i tak wychodziłby identyczny
Shalom
hashcode nie ma aż takiego znaczenia, bo możesz mieć dwa stringi z tym samym hashcode zwracające różne elementy mapy. Hashcode to jest pierwsza eliminacja elementów, ale jeśli są konflikty to rozpatrywane są za pomocą equals
V-2
Ma znaczenie w obrębie tego przykładu
katelx
@V-2 wydaje mi sie ze stringi (t.j. compile time literals + to co manualnie dodamy via string.intern) sa internowane niezaleznie od wielkosci
P7
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 16 godzin
  • Lokalizacja:Warszawa
  • Postów:89
0

@timati:
obczaj jeszcze jaki będzie wynik porównania s1 == s2 jeśli utworzysz Stringi w ten sposób

Kopiuj
String  s1 = new String("test");
String  s2 = new String ("test");

poczytaj co to string pool , bo pewnie będziesz nie raz pytany o te rzeczy na rozmowach

edytowany 1x, ostatnio: Pablitto77
OL
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 8 lat
  • Postów:13
0
Kopiuj
import java.util.HashMap;

public class mapy {
    public static void main(String[] args) {
	
	String s1 = new String("test");
    String s2 = new String("test");

    
    System.out.println(s1.hashCode());
    System.out.println(s2.hashCode());
    
    System.out.println(s1 == s2);
    System.out.println(s1.equals(s2));

    HashMap<String, String> map = new HashMap<>();
    map.put(s1,"cos");
    System.out.println(map.get(s2));
    }
}

Output
3556498
3556498
false
true
cos

Tutaj masz to wytlumaczone bardziej obrazowo, jak stosujesz

Kopiuj
String s1 = "test";
 String s2 = "test";
System.out.println(s1 == s2);

Output
true

Dlatego ze JVM jest na tyle sprytna i s2 wskazuje rowniez na to samo miejsce w pamieci gdzie znajduje sie s1.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.