如何根据 Java 列表中的重复获取前 N 个值

Rob*_*son 2 java sorting algorithm java-stream

我正在尝试根据 Java 列表中的重复来获取前 N 个值。

示例:查找前 2 个值
[“草莓”、“橙子”、“苹果”、“芒果”、“葡萄”、“菠萝”、“芒果”、“草莓”、“芒果”、“苹果”]

结果:
["mango"] //mango 重复了 3 次
["strawberries", "apple"] // "strawberries", "apple" 各重复了 2 次

我写了下面的代码来实现这一点

private static List<List<String>> getTop(int n, List<String> values) {

    Map<String, Long> valueCountMap = values.stream()
                           .collect(groupingBy(x -> x, counting()));

    final Map<String, Long> sortedByCount = valueCountMap.entrySet()
            .stream()
            .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new));

    List<List<String>> topNValues = new ArrayList<>();
    long prevValue = -1;
    for (Map.Entry<String, Long> e : sortedByCount.entrySet()) {
        if (prevValue == -1 || prevValue != e.getValue()) {
            if (topNValues.size() == n) {
                break;
            }
            prevValue = e.getValue();
            List<String> keys = new ArrayList<>();
            keys.add(e.getKey());
            topNValues.add(keys);
        } else if (prevValue == e.getValue()) {
            List<String> keys = topNValues.get(topNValues.size() - 1);
            keys.add(e.getKey());
        }
    }

    return topNValues;
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有更好的方法来实现这一点。性能和实施都明智。

sak*_*029 5

尝试这个。

private static List<List<String>> getTop(int n, List<String> values) {
    return values.stream()
        .collect(Collectors.groupingBy(s -> s, Collectors.counting()))
        .entrySet().stream()
        .collect(Collectors.groupingBy(Entry::getValue,
            TreeMap::new,
            Collectors.mapping(Entry::getKey, Collectors.toList())))
        .descendingMap().values().stream()
        .limit(n)
        .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)

输入

[strawberries, orange, apple, mango, grapes, pineapple, mango, strawberries, mango, apple]
Run Code Online (Sandbox Code Playgroud)

第一次的结果.collect()

{orange=1, apple=2, pineapple=1, strawberries=2, grapes=1, mango=3}
Run Code Online (Sandbox Code Playgroud)

第二个结果.collect()

{1=[orange, pineapple, grapes], 2=[apple, strawberries], 3=[mango]}
Run Code Online (Sandbox Code Playgroud)

的结果 .descendingMap()

{3=[mango], 2=[apple, strawberries], 1=[orange, pineapple, grapes]}
Run Code Online (Sandbox Code Playgroud)

最后的结果 .collect()

[[mango], [apple, strawberries]]
Run Code Online (Sandbox Code Playgroud)