2015-04-28 4 views
6

Ich habe eine Liste von commmons Pair, die es speichert Wörter und deren Frequenz wie die folgendeWie kann ich eine Liste von Paaren sortieren <String, Integer>?

private List<Pair<String, Integer>> words = new ArrayList<Pair<String, Integer>(); 

Ich versuche, zu sortieren, so dass, wenn ich über sie iterieren die Worte zu drucken, möchte ich die Worte mit dem höchsten Häufigkeit zuerst angezeigt.

Ich habe versucht zu spielen um Comparable mit der Umsetzung, aber die meisten Beispiele sind nicht ähnlich eine Liste von Paaren zu verwenden

+1

Sie sollten in der Lage sein, dies zu nutzen: http://stackoverflow.com/questions/16252269/how-to-sort-a-list-arraylist-in-java –

+0

Glaubst du nicht, es ist besser zu definieren, ein 'Paar' Klasse mit Wort und seiner Häufigkeit, anstatt die 'Paar'-Struktur von Commons zu verwenden. Auf diese Weise können Sie einfach einen benutzerdefinierten "Comparator" erstellen, um die Sortierkriterien basierend auf der Häufigkeit des Worts (oder) zu definieren. – Arkantos

+1

Warum verwenden Sie keine Map? Map wordsFrequencyMap; – ACV

Antwort

14

Sie eine benutzerdefinierte Comparator verwenden können:

Collections.sort(words, new Comparator<Pair<String, Integer>>() { 
    @Override 
    public int compare(final Pair<String, Integer> o1, final Pair<String, Integer> o2) { 
     // TODO: implement your logic here 
    } 
}); 
11

Um die Elemente zu sortieren nach absteigender Reihenfolge der Anzahl

Collections.sort(words, Comparator.comparing(p -> -p.getRight())); 

Dies wird das "Recht" des Paares in absteigender Reihenfolge verwenden.

Dies verwendet Java 8. Notional Sie Boxen den Wert und Integer.compareTo verwenden.

Allerdings kann mit der Escape-Analyse das Boxen eliminiert werden und Sie können keine Objekte erstellen.

+0

wird diese Unbox oder Integer compareTo? –

+0

@ BoristheSpider guter Punkt. –

2

Hallo ich denke, das sollte für Sie arbeiten.

List<Pair<String, Integer>> words = new ArrayList<Pair<String, Integer>>(); 
    words.add(new Pair<String, Integer>("hello",2)); 
    words.add(new Pair<String, Integer>("hello",1)); 
    words.add(new Pair<String, Integer>("aello",3)); 

    words.sort(new Comparator<Pair<String, Integer>>() { 
     @Override 
     public int compare(Pair<String, Integer> o1, Pair<String, Integer> o2) { 
      if (o1.getValue() > o2.getValue()) { 
       return -1; 
      } else if (o1.getValue().equals(o2.getValue())) { 
       return 0; // You can change this to make it then look at the 
          //words alphabetical order 
      } else { 
       return 1; 
      } 
     } 
    }); 

    System.out.println(words); 
+2

Glaubst du nicht, dass es besser wäre, sich auf compareTo() zu verlassen, das von Integer bereitgestellt wird, anstatt es selbst neu zu schreiben? –

+0

Sicher, aber wenn Sie die Werte alphabetisch weiter sortieren möchten, wenn die Frequenz gleich ist, macht das keinen großen Unterschied. Wenn nicht, wird Integer.compare zurückgegeben (o1.getValue(), o2.getValue()); ist einfacher ja. –

+2

@GregKing Oder Sie _could_ verwenden ['Comparator.thenComparing'] (https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#thenComparing-java.util.function.Function -java.util.Comparator-). Hängt davon ab, wieviel redundanter Code du schreiben willst, nehme ich an. –

2

Verwenden Sie eine Java 8 Lambda in Kombination mit Comparator.comparing (Sie müssen auch die Reihenfolge umgekehrt):

import static java.util.Collections.reverseOrder; 
import static java.util.Comparator.comparing; 

final List<Pair<String, Integer>> words = new ArrayList<>(); 
final Comparator<Pair<String, Integer>> c = reverseOrder(comparing(Pair::getValue)); 
Collections.sort(words, c); 

Der einfachste Weg, wenn man nur die Werte ausdrucken möchten Reihenfolge der Häufigkeit in absteigender Reihenfolge:

words.stream() 
     .sorted(c) 
     .map(Pair::getKey) 
     .forEach(System.out::println);