2015-05-13 11 views
9

Chcę zapisać wartość na podstawie klucza, złożonego z zestawu elementów. Coś jak na poniższym przykładzie. Oczywiście wiem, że mój pseudo-przykład nie zadziałałby, ponieważ hash obiektu będzie prawdopodobnie jego adresem, który będzie unikalny dla każdej nowej instancji, niezależnie od jej zawartości.Jak używać zestawu elementów jako klucza w mapach Java?

// in this pseudo-example this is my SET http://algs4.cs.princeton.edu/35applications/SET.java.html 
    // but the idea is that values are unique 
    HashMap<SET<Integer>, String> map = new HashMap<>(); 
    SET a = new SET(); 
    a.add(1); 
    a.add(2); 
    a.add(5); 

    SET b = new SET(); 
    b.add(5); 
    b.add(1); 
    b.add(2); 

    map.put(a, "w00t"); 

    System.out.println(map.get(b)); // I would want to get "w00t" because my key is the same set of elements 

Oczywiście mogę tylko rodzaj i złączyć wartości ustawione jako ciąg znaków, z separatorem i użyć jej w HashMap<String, String> konstrukcji, ale że po prostu nie czuję się dobrze. Jestem całkiem nowym programistą Java, więc może istnieć oczywiste rozwiązanie, którego mi brakuje.

+0

Musisz zajrzeć do 'keySet()'. Również jest "Set", a nie "SET" –

+0

Myślę, że jest tutaj duży problem, jeśli chcesz użyć kolekcji do tego zadania. Wszystkie są zmienne. Co się stanie, jeśli dodasz zestawy (2,3) i (1,2,3), ale wtedy zdecydujesz się usunąć {1} z drugiego zestawu? Lepiej stwórz do tego oddzielny niezmienny obiekt, w przeciwnym razie będzie to niepokojące. – pnadczuk

+0

Zdaję sobie z tego sprawę, ale w moim przypadku nie będę modyfikował obiektów po ich zapisaniu. Idealnie chciałbym mieć niezmienny obiekt, który inicjuję z innych iterowalnych, ale nie ma takiego, który mógłbym znaleźć :( – ddinchev

Odpowiedz

7

Jeśli używasz zamiast niestandardowego SET (jestem przy założeniu, że jest to klasa custom), to będzie działać dobrze, ponieważ HashSet zadajnikami hashCode i equals (a dokładnie, HashSet rozciąga AbstractSet które zastępują te metody), więc może służyć jako klucz w HashMap.

Jednakże, jeśli zmodyfikujesz Zestaw, który służy jako klucz w twojej Mapie, nie będziesz mógł później znaleźć tego klucza na Mapie. To ryzyko, na które natrafisz podczas używania obiektów zmiennych jako kluczy w HashMap.

HashMap<HashSet<Integer>, String> map = new HashMap<HashSet<Integer>, String>(); 
HashSet<Integer> a = new HashSet<Integer>(); 
a.add(1); 
a.add(2); 
a.add(5); 

HashSet<Integer> b = new HashSet<Integer>(); 
b.add(5); 
b.add(1); 
b.add(2); 

map.put(a, "w00t"); 

System.out.println(map.get(b)); 

Powoduje to wyprowadzenie w00t.

+0

To nie zastępuje, to po prostu dziedziczy – ddinchev

+1

@ddinchev Działa dobrze.Spróbuj i przekonaj się sam – gdejohn

+2

@ddinchev Tak, byłem niedokładny, AbstractSet ma nadrzędne – Eran

0

Utwórz klasę kolekcji i zastąp hashcode() w taki sposób, w jaki zwracany jest ten sam kod skrótu dla różnych instancji kolekcji o tej samej treści. Możesz po prostu przesłonić metodę w klasie pochodzącej z wybranej kolekcji. Musisz również ponownie zastosować equals (Object o).

+0

Implementacje zestawu JDK już to robią. – gdejohn

+0

Co powiesz na dwie instancje OrderedSet z innym Komparatorem? – Traubenfuchs

+0

Nadal działa. Jeśli zaznaczysz dokumenty dla ['TreeSet'] (https://docs.oracle.com/javase/8/docs/api/java/util/TreeSet.html), zobaczysz, że dziedziczy on jego [' równa się () '] (https://docs.oracle.com/javase/8/docs/api/java/util/AbstractSet.html#equals-java.lang.Object-) i [' hashCode() '] (https: //docs.oracle.com/javase/8/docs/api/java/util/AbstractSet.html#hashCode--) implementacje z 'AbstractSet'. "Interfejs Set umieszcza dodatkowe zastrzeżenia, poza dziedziczonymi z interfejsu Kolekcji, na umowach wszystkich konstruktorów oraz na kontraktach metod add, equals i hashCode." – gdejohn

-2

Nie dodałeś zestawu b do swojej mapy. Najpierw dodaj oba zestawy, a następnie spróbuj uzyskać wartość związaną z kluczem b.

+2

To punkt OP - oba zestawy mają te same elementy i powinny być identyczne, ale obiekt dodany z 'a', ponieważ klucz nie może być pobrany za pomocą' b'. Dzieje się tak, ponieważ nie zastąpił 'hashCode' lub' equals' w swojej implementacji zestawu niestandardowego. –

-1

To zależy od ciebie od implementacji klasy SET. Możesz rozszerzyć klasę java.util.HashSet lub zastosować metody equals() i hashCode() w klasie SET. Każde rozwiązanie będzie działać.

Powiązane problemy