2015-04-28 10 views
6

Ho una lista di Commmons Pair che memorizza le parole e la loro frequenza come la seguenteCome ordinare un elenco di coppie <String, Integer>?

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

che sto cercando di risolvere la cosa in modo che quando ho scorrere su di esso per stampare le parole, voglio che le parole con la più alta la frequenza di apparire per prima.

ho provato a giocare in giro con attuazione Comparable ma maggior parte degli esempi non sono simili ad usare una lista di coppie

+1

si dovrebbe essere in grado di utilizzare questo: http://stackoverflow.com/questions/16252269/how-to-sort-a-list-arraylist-in-java –

+0

non pensi che sia meglio definire un 'paio' classe con la parola e la sua frequenza invece di usare la struttura 'Pair' dai comuni. In questo modo puoi semplicemente creare un 'Comparatore 'personalizzato per definire i criteri di ordinamento in base alla parola (o) frequenza – Arkantos

+1

Perché non usi una mappa? Mappa wordsFrequencyMap; – ACV

risposta

14

È possibile utilizzare una consuetudine Comparator:

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

Per ordinare gli elementi per ordine di numero decrescente

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

Questo utilizzerà il "diritto" della coppia in ordine decrescente.

Questo utilizza Java 8. A livello teorico si sta utilizzando il valore di boxing e si utilizza Integer.compareTo.

Tuttavia, con l'analisi di fuga, la boxe può essere eliminata e non è possibile creare oggetti.

+0

aprirà questa casella o userà il confronto Integer? –

+0

@BoristheSpider buon punto. –

2

Ciao penso che questo dovrebbe funzionare per voi.

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

non pensi che basarsi su compareTo() fornito da Integer sarebbe meglio invece di riscriverlo da solo? –

+0

Certo, ma se si desidera ordinare ulteriormente i valori in ordine alfabetico se la frequenza è la stessa, non fa molta differenza. Ma se non lo sei, restituisci Integer.compare (o1.getValue(), o2.getValue()); è più facile, sì. –

+2

@GregKing O si potrebbe _utilizzare ['Comparator.thenComparing'] (https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#thenComparing-java.util.function.Function -java.util.Comparator-). Dipende da quanto codice ridondante si desidera scrivere suppongo. –

2

Utilizzare un Java 8 lambda in combinazione con Comparator.comparing (è anche necessario invertire l'ordine):

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

modo più semplice se si desidera solo per stampare i valori in ordine di frequenza decrescente:

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