2014-09-17 5 views
5

ich habe ein hashmap wie folgt aus:In Java, sortieren Hash-Karte durch seine 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); 

jetzt will ich durch seine Schlüssellänge um diese Karte sortieren, wenn zwei Schlüssel gleich lang sind (zB Gehe und C# beide Länge 2), dann sortiert nach alphba Ordnung. so das Ergebnis i zu erhalten erwarten ist so etwas wie:

Drucker: Objective-c, 11 java, 4 C#, 2 gehen, 2

hier ist meine eigene attamp, aber es tut überhaupt arbeitet ...

 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()); 
        } 
       } 
     ); 

tatsächlich die ‚compareTo‘ -Methode als rot erscheint (nicht kompilieren können) .... bitte jemand mir mit einigem Code Beispiel helfen ... ich bin ein wenig verwirrend mit, wie Komparator-Klasse verwendet wird, um compa anzupassen Re-Objekt ...

Antwort

12

Der Compiler beschwert sich, weil Sie nicht compareTo auf einem int aufrufen können. Der richtige Weg, um die Karte zu sortieren, ist die folgende:

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); 
      } 
     } 
}); 

Die ersten beiden Bedingungen, um die Längen der beiden String s vergleichen und eine positive oder eine negative Zahl entsprechend zurück. Die dritte Bedingung würde die String s lexikographisch vergleichen, wenn ihre Längen gleich sind.

2

weil length() nicht definiert compareTo Methode das ist, warum Sie Fehler sehen. Zur Korrektur verwenden Sie es Integer.compare(s1.length(), s2.length()); aktualisierten Code unter

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

, wenn Sie Ihren Code ausführen, ist das Ergebnis {C# = 2, java = 4, Objective-C = 11}. Die Frage ist, wo ist das "gehen", 2? –

+0

Es ist aufgrund der Tatsache, dass TreeMap Comparator und Komparator verwendet wird definiert, um 2 Strings gleicher Länge als gleich behandeln. Da OP mit TreeMap gespielt hat, habe ich seine Antwort erweitert, um nur den Comparator-Part zu korrigieren. – sol4me

+0

oh cool was denkst du über meine Antwort? Da die Op nicht erwähnt, dass die Verwendung von Treemap ist zwingend erforderlich, habe ich einen anderen Stil verwendet –

-1

sollte der Komparator sein:

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

Funktioniert nicht. Wenn die beiden Strings die gleiche Länge haben und eine TreeMap zum Sortieren verwenden, berücksichtigt sie String-Schlüssel gleicher Länge wie Duplikate und entfernt sie. –

4

Sie rufen String#length(), die eine primitive int zurückgibt. Sie benötigen die statische Methode Integer.compare(int,int). Wenn Sie auf Java 8 sind, können Sie sich eine Menge Tipparbeit sparen:

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

Sir Ihr Out Put ist {}? –

+1

Mein Code versucht keine Ausgabe, aber wenn Sie nach der String-Darstellung einer leeren Map fragen, haben Sie Recht. –

+0

Ich habe diese Frage gepostet. wenn Sie http://stackoverflow.com/questions/25905445/apply-distinct-function-on-treemap antworten können –

1

Bei Verwendung des TreeMap ist nicht zwingend

explantion: Definieren eines Comaprator, und im nächsten Schritt definieren Sie eine Liste, damit wir alle Karteneinträge zu einer Liste hinzufügen können.Am Ende, sortieren Sie die Liste von definierten Comaprator

-Code:

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)); 

Ausgang:

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

Hinweis: nach Anzahl sortiert bekommen

, wenn es muss comparis machen basierend auf Schlüssel kann die folgende Zeile verwendet werden.

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(); 
     }