Java 8 - 单词计数然后以desc顺序排列

bhu*_*pen 3 java java-8 java-stream collectors

比方说,我有一个单词列表

List<String> words = Arrays.asList("Hello alan i am here where are you"+  
  "and what are you doing hello are you there");
Run Code Online (Sandbox Code Playgroud)

如何按降序排列列表中重复多次的前七个单词?然后单个输入词应按字母顺序排列.所以上面的输出应该是前七个字

you (3)
are (2)
hello (2)
alan (1)
am (1)
and (1)
doing (1)
Run Code Online (Sandbox Code Playgroud)

我正在使用流,lamda在Java 8中这样做.

我正在尝试这种方式.首先对列表进行排序第二次获取单词的地图及其单词列表中的单词数量.

List<String> sortedWords = Arrays.asList("Hello alan i am here where are you and what are you doing hello you there".split(" "))
            .stream().sorted().collect(toList());

Map<String, Long> collect = 
            sortedWords.stream().collect(groupingBy(Function.identity(), counting()));
Run Code Online (Sandbox Code Playgroud)

Tun*_*aki 9

最困难的部分是分拣.由于您只想保留结果中的7个第一个元素,并且您希望按其值对Map进行排序,因此我们需要创建所有结果的Map,对其进行排序,然后保留7个结果.

在下面的代码中,每个单词都是低位的,并按自己分组,计算出现的次数.然后,我们需要对这个映射进行排序,以便我们在条目上创建一个Stream,根据值(按降序排序)然后根据键对它们进行排序.保留7个第一个元素,映射到它们的键(对应于单词)并收集到a中List,从而保持相遇顺序.

public static void main(String[] args) {
    String sentence = "Hello alan i am here where are you and what are you doing hello are you there";
    List<String> words = Arrays.asList(sentence.split(" "));

    List<String> result = 
            words.stream()
                 .map(String::toLowerCase)
                 .collect(groupingBy(identity(), counting()))
                 .entrySet().stream()
                 .sorted(Map.Entry.<String, Long> comparingByValue(reverseOrder()).thenComparing(Map.Entry.comparingByKey()))
                 .limit(7)
                 .map(Map.Entry::getKey)
                 .collect(toList());

    System.out.println(result);
}
Run Code Online (Sandbox Code Playgroud)

输出:

[are, you, hello, alan, am, and, doing]
Run Code Online (Sandbox Code Playgroud)

请注意,您在想要的输出中犯了一个错误:"are"实际上出现了3次,就像"you"之前一样

注意:这段代码假定有很多静态导入,即:

import static java.util.Comparator.reverseOrder;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
Run Code Online (Sandbox Code Playgroud)

  • 我在这里的偏好是制作这两个显式的流管道,而不是在"中间"中执行.entrySet().stream(),因为它使得更清楚实际发生了什么 - 你正在执行两个不同的流操作.这增强了可读性,而没有任何运行时成本.(更一般地说,虽然方法链是烹饪,但它很容易过度 - 只是因为你可以链接,并不意味着你必须一直这样做.) (3认同)