如何对Pair<String,Integer>列表进行排序?

15

我有一个常见词汇的列表Pair,它存储单词及其频率,如下所示。

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

我希望对它进行排序,以便在迭代打印单词时,希望出现最高频率的单词第一个。

我尝试使用实现Comparable的方式进行操作,但大多数示例与使用Pairs列表不相似。


1
你应该能够使用这个:https://dev59.com/OWQo5IYBdhLWcg3wMs4L - Chris Bolton
1
你不觉得定义一个包含单词和频率的Pair类比使用commons中的Pair结构更好吗?这样,你可以简单地创建一个自定义的Comparator来定义基于单词或频率的排序标准。 - Arkantos
1
为什么不使用Map呢?Map<String, Integer> wordsFrequencyMap; - ACV
4个回答

25

按数字降序排列元素

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

这将按降序使用“对”的右边。

这使用Java 8。概念上,您正在对值进行装箱并使用Integer.compareTo。

然而,通过逃逸分析,可以消除装箱,并且您可能不会创建任何对象。


这会使用自动拆箱或者使用Integer的compareTo方法? - guido
破折号前的p是什么意思? - Desert Scuba
1
@DesertScuba 这是一个负数运算符。它会颠倒顺序。例如,3 < 5,但 -3 > -5。 - Peter Lawrey

20

您可以使用自定义的比较器

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

3

你好,我认为这对你来说应该能够工作。

 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
你不觉得依赖于 Integer 提供的 compareTo() 方法比自己重写更好吗? - guido
当然,如果您想进一步按字母顺序对值进行排序,如果频率相同,则没有太大区别。但是,如果您不这样做,返回Integer.compare(o1.getValue(),o2.getValue())会更容易。 - Greg King
2
@GregKing 或者你可以使用 Comparator.thenComparing。这取决于你想要写多少冗余代码。 - Boris the Spider

3

使用Java 8 lambda结合Comparator.comparing(您还需要反转顺序):

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

如果您只想按频率降序打印值,则最简单的方法是:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接