Sortowanie HashMap po wartościach.

Sortowanie HashMap po wartościach.
M3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 42
0

Robię tak, jak w kodzie poniżej, ale przy rzutowaniu na Entry wywala błąd (ClassCastException). Dlaczego? Jeśli tak, jak robię się nie da, to piszcie jak posortować HashMap po wartościach?

Dostaję nulla, po rzutowaniu na Entry<String, Integer>. Wie ktoś dlaczego?

Kopiuj
                      
            	HashMap<String, Integer> records;

                       Set<Entry<String,Integer>> set = records.entrySet();
		
		Map.Entry<String,Integer>[] aRecords = set.toArray(aRecords);
		
		
		Arrays.sort(aRecords, 
				new Comparator<Map.Entry<String, Integer>>() {
			
			public int compare(
					Map.Entry<String, Integer> e1,
					Map.Entry<String, Integer> e2) {
				
				if (e1.getValue() < e2.getValue())
					return -1;
				else if (e1.getValue() > e2.getValue())
					return 1;
				else
					return 0;
			}
			
		});
Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
0

Jaki błąd i w którym miejscu?

Edit:
Poza tym czemu nagle z Entry zrobiło ci się Map.Entry?

M3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 42
0
Wibowit napisał(a)

Jaki błąd i w którym miejscu?

Edit:
Poza tym czemu nagle z Entry zrobiło ci się Map.Entry?

Bo chodzi o Entry z Map, to to samo

Nie wiem o co ci chodzi z tym nullem.
Wypisywałem records bez sortowania i działało dobrze.

  • Rejestracja: dni
  • Ostatnio: dni
1

Jak potrzebujesz sortowania to moze uzyj TreeMap? Wtedy podczas wstawiania od razu jest wstawiane w odpowiedni emiejsce tak aby podczas iterowania bylo ladnie po kolei.

M3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 42
0
::. napisał(a)

Jak potrzebujesz sortowania to moze uzyj TreeMap? Wtedy podczas wstawiania od razu jest wstawiane w odpowiedni emiejsce tak aby podczas iterowania bylo ladnie po kolei.

Dobra rada, ale chcę móc sortować po wartościach i po kluczach, a dopisywać jak do mapy po kluczach, czyli muszę mieć implementację sortowania po wartościach. No i tutaj się staram dowiedzieć, czy jest to możliwe.

M3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 42
0

Dobra, więc mój problem na końcu polegał na tym, że metoda HashMap.EntrySet().toArray() nie działała, no więc zrobiłem to inaczej.

Z HashMap biorę listę elementów:
List list = new Vector(HashMap.entrySet());

potem to sortuję jak chcę przez

Kopiuj
Collections.sort(list, new Comparator<Entry<String, Integer>() {

			public int compare(Map.Entry<String, Integer> e1,
					Entry<String, Integer> e2) {

				Integer i1 = e1.getValue();
				Integer i2 = e2.getValue();
				
				if (i1 < i2)
					return -1;
				else if (i1 > i2)
					return 1;
				else return 0;
			}

Kod ze stronki jaką znalazłem:

Kopiuj
Map<String, Integer> map = new HashMap<String, Integer>();

    // --- Put entries into map here ---

    // Get a list of the entries in the map
    List<Map.Entry<String, Integer>> list = new Vector<Map.Entry<String, Integer>>(map.entrySet());

    // Sort the list using an annonymous inner class implementing Comparator for the compare method
    java.util.Collections.sort(list, new Comparator<Map.Entry<String, Integer>>(){
        public int compare(Map.Entry<String, Integer> entry, Map.Entry<String, Integer> entry1)
        {
            // Return 0 for a match, -1 for less than and +1 for more then
            return (entry.getValue().equals(entry1.getValue()) ? 0 : (entry.getValue() > entry1.getValue() ? 1 : -1));
        }
    }); 
iooi
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 573
0
Kopiuj
Comparator<Map.Entry<String, Integer>> comparator = new Comparator<Map.Entry<String, Integer>>() {
    public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
        return e1.getValue().compareTo(e2.getValue());
    }
};
TreeSet<Map.Entry<String, Integer>> entries = new TreeSet<Map.Entry<String, Integer>>(comparator);
entries.addAll(map.entrySet());
Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
0

A może wystarczyłaby jakaś kolekcja z paczki od Googla: http://code.google.com/p/guava-libraries/ ?

M3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 42
0

Najprościej można to zrobić tworząc 2 mapy. Przejrzałem te kolekcje google no i tam nie znalazłem żadnej takiej kolekcji.

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
0

Tylko, że wtedy albo jedna musi być multimapą (jest taka w guava-libraries) albo ręcznie musisz sprawdzać (i wyrzucać) czy wartości się w nich nie powtarzają.

Np:
Map[A, B] mapaA;
Map[B, A] mapaB;

Teraz dodajemy parę (A a, B b):
B stareB = mapaA.put(a, b);
mapaB.remove(stareB);
A stareA = mapaB.put(b, a);
mapaA.remove(stareA);

Chyba poprawne. Nietestowane, na szybko pisane :)

W guava-libraries jest BiMap tyle, że są albo Enum albo HashBiMap, więc nie ma posortowanej BiMapy.

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.