2012-01-28 18 views
8

mam jeden problemJak sortować klucze HashMap

HashMap<String, List<AppPrjMilestone>> dateMilestoneMap 
           = new HashMap<String, List<AppPrjMilestone>>(); 

kładę klucz dynamiczny w obiekcie HashMap tak:

dateMilestoneMap.put(""+crateDate,value); 

Wreszcie jestem coraz wynik tak:

("28/01/2012",value) 
("01/01/2012",value) 
("26/01/2012",value) 

Chcę, aby pary wartości zwracanych kluczy były w porządku desc lub asc. Jak mogę to zrobić?

+1

Wypróbuj mapę drzewa i przeczytaj dokumentację Javadoc: http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html – home

+0

Każdy powód, dla którego używasz mapy zamiast listy? – kba

+0

TreeMap to proste rozwiązanie. Więcej dyskusji na ten temat można znaleźć na http://stackoverflow.com/questions/7860822/sorting-hashmap-based-on-keys – Bob

Odpowiedz

20

HashMaps nie zapisuje posortowanej kolejności klawiszy z definicji. Można to jednak osiągnąć, pobierając tablicę kluczy za pomocą: Object[] keys = map.keySet().toArray(); Następnie sortując listę za pomocą tablic: Arrays.sort(keys); i na koniec powtarzając każdy klucz i pobierając wartość z HashMap.

for(Object key : keys) { System.out.println(map.get(key)); }

Sortujący krok spowoduje, że przebieg algorytm O (n log n) zamiast O (n), który jest możliwy do przeprowadzenia z wykorzystaniem sortowania struktury danych.

Spowoduje to leksykograficzną sortację listy. Ponieważ wygląda na to, że twoje pytanie używa wspólnego amerykańskiego formatu daty, posortuje listę według dnia, miesiąca i wreszcie roku. Jest to mało prawdopodobne. Możesz użyć formatu daty na rok, miesiąc, dzień lub przyjąć bardziej odpowiedni obiekt klucza. Kompozycje DateTime i DateTimeCoda byłyby bardzo użyteczne. Po prostu użyj DateTime jako klucza i instancji DateTimeComparator podczas wywoływania Arrays.sort(keys, comparator);.

+0

Dlaczego nie 'Collection.sort'? A dlaczego nie użyć komparatora na 'Map.Entry'? –

+1

Collections.sort (...) działa, ale pobiera listę, której HashMap nie implementuje. Konieczne byłoby przekonwertowanie go na coś takiego jak ArrayList za pośrednictwem nowej tablicy ArrayList (mapa). W końcu jego zasadniczo ten sam mechanizm. Jeśli klawisze są łańcuchami, zostaną posortowane leksykograficznie. – allingeek

+0

Można sortować Map.keySet(). – user949300

0

Proponuję zmienić klucz HashMap z ciągu na dzień, np. HashMap<Date, List<AppPrjMilestone>>. To powinno wystarczyć.

Ups - sprawiają, że TreeMap<Date, List<AppPrjMilestone>>

+1

Nie, nie powinno. – vitaut

2

HashMap nie przewiduje żadnego uporządkowania gdy iteracyjne nad nim (lub nawet zagwarantować, że kolejność pozostanie taka sama jeśli pętla wielokrotnie). Jeśli chcesz uzyskać naturalne porządkowanie kluczy, spróbuj TreeMap. Zauważ, że twoje struny są sformatowane dd/mm/yy, więc kiedy TreeMap zamawia je, będą one rosły pierwszego dnia, a nie roku, co prawdopodobnie nie jest tym, czego potrzebujesz. Należy użyć ciągi jak yy/mm/dd, przełączyć się za pomocą klasy, która zamyka tę informację lepiej jak Date lub zdefiniować własne Comparator podczas konstruowania TreeMap który wie, jak uporządkować dd/mm/yy sznurki w odpowiedniej kolejności

+1

Jestem prawie pewien, że pytanie dotyczyło sortowania kluczy HashMap. – allingeek

+0

@allingeek Nie jestem. Był niejasny, ale myślę, że chce zapętlić mapę i uzyskać klucze w porządku rosnącym lub malejącym, więc powinien po prostu użyć mapy, która to zapewnia. Jeśli jest to dosłownie "muszę użyć HashMap, ale i tak chcę kluczy", powinien to określić, ale myślę, że to coś więcej "Używam HashMap, ale nie robię tego, co chcę, jak to zrobić sobie z tym poradzić?" –

+0

Tworzenie kopii mapy mapy HashMap może być najlepszym sposobem sortowania kluczy. –

0

HashMap robi” t określić kolejność iteracji po elementach. Jeśli chcesz odzyskać elementy posortowane według klucza, użyj zamiast tego TreeMap. Jednakże, ponieważ przechowujesz ciągi znaków w formacie "DD/MM/RRRR", kolejność będzie prawdopodobnie inna niż ta, którą chcesz, więc użyj daty jako klucza lub przynajmniej ciągu znaków takiego jak "RRRR-MM-DD ".

3

Klucze mapy są przechowywane w Set, których nie można sortować. Możesz to zrobić, dodając klucze zestawu map do List i zamiast tego sortując.

np.

List<Date> sortedKeys = new ArrayList<Date>(dateMilestoneMap.size()); 
sortedKeys.addAll(dateMilestoneMap.keySet()); 
Collections.sort(sortedKeys); //sorts in ascending date order 
          //(pass in custom Comparator to sort differently).. 

Tutaj użyłem klasy Date który jest znacznie lepszy do przechowywania dat niż zwykły pszczół.