【问题标题】:Most concise way to get highest n numbers out of a map?从地图中获取最高 n 个数字的最简洁方法?
【发布时间】:2014-02-13 10:16:43
【问题描述】:

我已经有了以下内容:

public enum InvoiceCurrency {
    EUR(
            s -> (s.contains("€") || s.contains("EUR"))
    ),
    USD(
            s -> (s.contains("$") || s.contains("USD"))
    );

    private final Predicate<String> predicate;

    InvoiceCurrency(final Predicate<String> predicate) {
        this.predicate = predicate;
    }

    public boolean matchesString(final String value) {
        return predicate.test(value);
    }

    public static EnumMap<InvoiceCurrency, Integer> createMapping(final Stream<String> valuesStream) {
        EnumMap<InvoiceCurrency, Integer> mapping = new EnumMap<>(InvoiceCurrency.class);
        mapping.replaceAll((k, v) -> 0);
        Stream<InvoiceCurrency> enums = Arrays.stream(InvoiceCurrency.values());
        valuesStream.forEach(
            s -> enums.forEach(
                e -> {
                    if (e.matchesString(s)) {
                        mapping.compute(e, (k, v) -> v++);
                    }
                }
            )
        );
        return mapping;
    }
}

private InvoiceCurrency calculateCurrency() {
    EnumMap<InvoiceCurrency, Integer> map = InvoiceCurrency.createMapping(data.words.stream().map(w -> w.content));
    InvoiceCurrency maximum = map.entrySet().parallelStream().  //how to continue?
}

这会导致从枚举到“出现次数”的映射,因此 EUR 可以映射到 10USD1。可能,计数可能相同。

现在我是否尽可能简洁并能够使用java-8,得到属于最高数字的InvoiceCurrency?有没有一种简洁的方法可以看到排序后的整数计数的前 2 个实际上具有相同的值?

我知道我可以使用循环等对其进行编程,但我希望依靠java-8 精神来获得最可维护的代码。

【问题讨论】:

    标签: java dictionary enums java-8 java-stream


    【解决方案1】:

    带有Map&lt;String, Integer&gt; 的简单示例,但同样适用于您的示例。打印前 2 个条目(b 和 c 或 d)。

    import static java.util.Collections.reverseOrder;
    import static java.util.Comparator.comparingInt;
    //...
    
    Map<String, Integer> map = new HashMap<>();
    map.put("a", 2);
    map.put("b", 10);
    map.put("c", 5);
    map.put("d", 5);
    map.put("e", 1);
    
    map.entrySet().parallelStream()
            .sorted(reverseOrder(comparingInt(Map.Entry::getValue)))
            .limit(2)
            .forEach(System.out::println);
    
    //or:   .forEachOrdered(System.out::println);
    //to print in descending order
    

    注意:从 b129 开始,您还可以使用 sorted(comparingInt(Map.Entry::getValue).reversed()) 代替 sorted(reverseOrder(comparingInt(Map.Entry::getValue)))

    【讨论】:

    • 目前看起来很不错!尤其是自从您上次编辑以来,有没有办法明确地反转比较器?
    • 是的,仍然难以理解为什么 Comparator.comparingInt(Map.Entry::getValue).reversed() 不起作用,即使是在明确的定义中(不是 lambda 语句)。
    • 虽然它适用于Comparator.&lt;String&gt;comparingInt(String::length).reversed(),但是我认为你不能使用导入或将类型参数放入该函数?
    • @skiwi 是的 - 我不知道为什么。
    猜你喜欢
    • 2016-06-22
    • 2014-08-17
    • 2016-07-15
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 2015-11-29
    • 2014-05-22
    • 2022-01-21
    相关资源
    最近更新 更多