使用lambda获取Map <K,V>的最大键

Jay*_*Jay 8 java lambda map max java-8

我有一个,Map<Float, String>并希望得到所有键的最大值.在C#中我会做这样的事情:

var dictionary = new Dictionary<float, string>{{5,"foo"}, {42, "bar"}, {0, "foobarz"}};
float max = dictionary.Max(x => x.Key); //42
Run Code Online (Sandbox Code Playgroud)

现在我正在寻找一种方法来使用Java 8 lambdas做同样的事情,但我得到的最接近的是:

float max = (float)map.keySet().stream().mapToDouble((x) -> x).summaryStatistics().getMax();
Run Code Online (Sandbox Code Playgroud)

这看起来很糟糕,需要完全不必要的类型转换.有一个更好的方法吗?

nos*_*sid 14

该接口Stream包含max获取最大元素的方法.您可以使用方法引用作为Comparator.该方法max返回一个Optional<Float>,因为空流中没有最大元素.您可以使用该方法orElse为此案例提供替代值.

float max = map.keySet().stream().max(Float::compareTo).orElse(0.0f);
Run Code Online (Sandbox Code Playgroud)

  • @nosid你认为在实践中会有任何性能差异吗?我希望`floatValue()`的调用将被内联,一旦JIT被调用就产生相同的代码. (2认同)

Bri*_*etz 14

有一个比在keySet()上运行更直接的解决方案; 使用添加的比较器工厂直接在entrySet()上运行Map.Entry.

Map.Entry<K,V> maxElt = map.entrySet().stream()
                           .max(Map.Entry.comparingByKey())
                           .orElse(...);
Run Code Online (Sandbox Code Playgroud)

这不仅允许获取最小/最大元素,还允许排序,因此很容易找到前十个键/值对,如下所示:

Stream<Map.Entry<K,V>> topTen = map.entrySet().stream()
                                   .sorted(Map.Entry.byKeyComparator().reversed())
                                   .limit(10);
Run Code Online (Sandbox Code Playgroud)