2014-09-17 19 views
5

mam HashMap takiego:W Javie, sortowanie hash mapie jego key.length()

HashMap<String,Integer> map = new HashMap<String,Integer>(); 
map.put("java",4); 
map.put("go",2); 
map.put("objective-c",11); 
map.put("c#",2); 

Teraz chcę uporządkować tę mapę przez jej długości klucza, jeśli dwa klawisze długości są równe (np idź i C# obie długości 2), a następnie posortowane według porządku alfba. więc wynik spodziewam się dostać to coś w rodzaju:

wydrukowany wynik: objective-c, 11 java, 4 C#, 2 iść, 2

tutaj jest mój własny attamp, ale to nie robi działa w ogóle ...

 HashMap<String,Integer> map = new HashMap<String,Integer>(); 
      map.put("java",4); 
      map.put("go",2); 
      map.put("objective-c",11); 
      map.put("c#",2); 

     Map<String,Integer> treeMap = new TreeMap<String, Integer>(
       new Comparator<String>() { 
        @Override 
        public int compare(String s1, String s2) { 
         return s1.length().compareTo(s2.length()); 
        } 
       } 
     ); 

rzeczywiście pojawia się w sposób „” compareTo jako czerwony (nie móc skompilować) .... proszę mi ktoś pomóc z jakimś przykładzie kodu ... jestem nieco mylące jak używać klasy komparatora do dostosowywania kompa ponownie obiekt ...

Odpowiedz

12

Kompilator narzeka, ponieważ nie można nazwać compareTo na int. Prawidłowy sposób sortowania mapę jest następujący:

Map<String, Integer> treeMap = new TreeMap<String, Integer>(
    new Comparator<String>() { 
     @Override 
     public int compare(String s1, String s2) { 
      if (s1.length() > s2.length()) { 
       return -1; 
      } else if (s1.length() < s2.length()) { 
       return 1; 
      } else { 
       return s1.compareTo(s2); 
      } 
     } 
}); 

Pierwsze dwa warunki porównanie długości dwóch String s i powrócić dodatnią lub ujemną liczbę odpowiednio. Trzeci warunek porównałby leksykograficznie, jeśli ich długości są równe.

2

ponieważ length() nie definiuje metody compareTo dlatego pojawia się błąd. Aby poprawić używać Integer.compare(s1.length(), s2.length()); zaktualizowany kod poniżej

import java.util.Comparator; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.TreeMap; 

public class Test { 

    public static void main(String[] args) { 

     HashMap<String,Integer> map = new HashMap<String,Integer>(); 
     map.put("java",4); 
     map.put("go",2); 
     map.put("objective-c",11); 
     map.put("c#",2); 


     Map<String,Integer> treeMap = new TreeMap<String, Integer>(
       new Comparator<String>() { 
        @Override 
        public int compare(String s1, String s2) { 
         return Integer.compare(s1.length(), s2.length()); 
        } 
       } 
     ); 

     treeMap.putAll(map); 

     System.out.println(treeMap); 
    } 
} 
+1

podczas uruchamiania kodu, rezultat jest {c = 2 #, Java = 4, objective-c = 11}. pytanie brzmi: "idź", 2? –

+0

Jest to spowodowane tym, że TreeMap używa komparatora, a komparator jest zdefiniowany tak, aby traktować 2 struny o jednakowej długości. Ponieważ OP grał z TreeMap, więc przedłużyłem jego odpowiedź, aby poprawić tylko część Komparatora. – sol4me

+0

o co słychać, co myślisz o mojej odpowiedzi? ponieważ operacja nie wspomniała, że ​​używanie treemap jest obowiązkowe użyłem innego stylu –

-1

Komparator powinno być:

new Comparator<String>() { 
    @Override 
    public int compare(String s1, String s2) { 
     return Integer.compare(s1.length(), s2.length()); 
    } 
} 
+3

Nie działa. Jeśli dwa ciągi mają tę samą długość i przy użyciu mapy drzewa do sortowania, będą uwzględniały klucze typu String o tej samej długości co duplikaty i usuwają je. –

4

zadzwonić String#length(), która zwraca prymitywne int. Potrzebujesz statycznej metody Integer.compare(int,int). Jeśli jesteś na Java 8 można zaoszczędzić dużo wpisując:

Map<String,Integer> treeMap = new TreeMap<>(
     Comparator.comparingInt(String::length) 
        .thenComparing(Function.identity())); 
+0

Proszę pana, czy to jest {}? –

+1

Mój kod nie próbować wyjścia, ale jeśli pytasz o reprezentację ciąg pusty mapie, a następnie masz rację. –

+0

Wysłałem to pytanie. jeśli możesz odpowiedzieć na http://stackoverflow.com/questions/25905445/apply-distinct-function-on-treemap –

1

przypadku korzystania z TreeMap jest nie obowiązkowe

WYJAŚNIENIE: Zdefiniuj Comaprator, a następnie krok, zdefiniuj listę, abyśmy mogli dodać wszystkie pozycje mapy do listy.Na koniec, posortować listę według zdefiniowanego Comaprator

Kodeksu:

Comparator<Map.Entry<String,Integer>> byMapValues = 
     (Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) ->left.getValue().compareTo(right.getValue()); 

List<Map.Entry<String,Integer>> list = new ArrayList<>(); 
list.addAll(map.entrySet()); 
Collections.sort(list, byMapValues); 
list.forEach(i -> System.out.println(i)); 

Output:

c#=2 
go=2 
java=4 
objective-c=11 

Uwaga: się posortowana według liczby

jeśli istnieje trzeba zrobić porównanie na podstawie klucza można użyć następującej linii.

Comparator<Map.Entry<String,Integer>> byMapKeys = 
      (Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) -> left.getKey().compareTo(right.getKey()); 
1
 public int compare(String o1, String o2) { 
      return o1.length() == o2.length() ? o1.compareTo(o2) : o1.length() - o2.length(); 
     } 
Powiązane problemy