2015-04-28 32 views
6

Mam listę commmons Pair przechowującego słów i ich częstotliwość, jak na poniższymJak mogę posortować listę pary <String, Integer>?

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

próbuję rozwiązać to tak, że kiedy iteracyjne nad nim wydrukować te słowa, chcę słowa z najwyższym częstotliwość pojawiać się jako pierwsza.

Próbowałem gry z realizacji Comparable ale większość przykładów nie są podobne do korzystania listę par

+1

Powinieneś być w stanie korzystać z tego: http://stackoverflow.com/questions/16252269/how-to-sort-a-list-arraylist-in-java –

+0

nie sądzisz, że lepiej jest określić a "Para" klasa ze słowem i jego częstotliwością zamiast używać struktury "Pair" z commons. W ten sposób możesz po prostu utworzyć niestandardowy "Komparator", aby zdefiniować kryteria sortowania na podstawie słowa (lub) częstotliwości – Arkantos

+1

Dlaczego nie używasz mapy? Mapa wordsFrequencyMap; – ACV

Odpowiedz

14

Można użyć niestandardowego 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

Aby posortować elementy Postanowieniem liczby maleje

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

Spowoduje to użycie "prawa" pary w porządku malejącym.

Używa Java 8. Podsumowując, podważasz wartość i używasz Integer.compareTo.

Jednak dzięki analizie ucieczki boks można wyeliminować i nie można tworzyć żadnych obiektów.

+0

Czy to rozwinie lub użyje funkcji Integer compareTo? –

+0

@BoristheSpider dobry punkt. –

2

Witam, myślę, że to powinno zadziałać.

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

nie sądzisz, że poleganie na compareTo() dostarczonym przez Integer byłoby lepsze zamiast przepisywania go samemu? –

+0

Oczywiście, ale jeśli chcesz dalej posortować wartości alfabetycznie, jeśli częstotliwość jest taka sama, to nie robi dużej różnicy. Ale jeśli nie, zwracaj Integer.compare (o1.getValue(), o2.getValue()); jest łatwiejsze tak. –

+2

@GregKing Lub możesz użyć '' Comparator.thenComparing'] (https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#thenComparing-java.util.function.Function -java.util.Comparator-). Zależy, ile przypuszczam redundantnego kodu, który chcesz napisać. –

2

Użyj Java 8 lambda w połączeniu z Comparator.comparing (trzeba także odwrócić kolejność):

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

Najłatwiej jeśli chcesz po prostu wydrukować wartości w kolejności częstotliwości malejącym:

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