使用Comparator对ArrayList进行排序



我一直在做一个拼字游戏的作业。我需要从列表中读取单词,然后读取每个字符并赋值,最终为每个单词分配总分。已经做到了!唷。现在我需要使用Comparator将单词从最高分数到最低分数排序。我读了很多书,但我还是很困惑。我知道我可以使用接口,但也可以使用带lambda表达式的Comparator,这是我想要的方向。我只是不知道该怎么做。我需要比较每个单词的sumValue,然后按降序打印单词。

我创建了2个循环来读取单词(I),然后是字符(j)。我在屏幕上打印了每个单词(sumValue)的分数和它在数组列表中的位置(I)。现在我需要使用Comparator来比较分数,然后重新排序位置。我觉得我的问题是我感觉我没有对数组列表排序。我在排序分数,它不在数组列表中。我是否需要创建一个新的数组列表,将分数附加到每个单词并对其进行排序?

你可以这样做。List接口有一个sort()方法,它接受aComparator .

定义比较器的常见做法是使用它的静态方法之一,如Comparator.comparing(Function<? super T,? extends U> keyExtractor)。在本例中,KeyExtractor将是Word.getValue方法指定为方法引用(lambda也可以)。

但是首先,您应该创建一个recordclass来保存单词和值。这样,当您根据值对记录进行排序时,单词和值仍将作为一个单位在一起。

record Word(String getWord, int getValue) {
     @Override
     public String toString() {
         return "%s -> %d".formatted(getWord, getValue);
     }
}

在这里我创建了一个Word记录的列表。为了演示,这些值是任意的。

List<Word> list = new ArrayList<>(
       List.of(new Word("the", 30), new Word("Hello", 20), new Word("GoodBye", 2)));
list.sort(Comparator.comparing(Word::getValue));
System.out.println(list);

打印

[GoodBye -> 2, Hello -> 20, the -> 30]

也可以逆序排序

list.sort(Comparator.comparing(Word::getValue).reversed());
System.out.println(list);

打印

[GoodBye -> 2, Hello -> 20, the -> 30]

我还建议使用Map来保存字母和它们的点值。

Map<String, Integer> letterMap = Map.of("A",1,"B",1,"C",1, ....);

那么你可以像这样访问它们

int point = letterMap.get("A");

所以你有一个分数计算方法:

int score(String word) {
    ...
}

和单词列表:

Path path = Paths.get("C:/words.txt");
List<String> words = Files.readAllLines(path, Charset.defaultCharset());
words.sort(Comparator.comparingInt(this::score)
                     .thenComparing(Function.identity()));

这将首先对分数进行排序,然后对相同的分数按字母顺序排序。

比较/comparingInt/ComparingDouble/…函数表示将给出一个比较键(来自单词)的函数。为了比较它们自己的单词,Function.identity()将使用单词本身。

相关内容

  • 没有找到相关文章

最新更新