Java 获取地图的最大键<;K、 V>;使用lambda

Java 获取地图的最大键<;K、 V>;使用lambda,java,map,lambda,max,java-8,Java,Map,Lambda,Max,Java 8,我有一张地图,希望获得所有钥匙的最大值。在C#中,我会这样做: var dictionary = new Dictionary<float, string>{{5,"foo"}, {42, "bar"}, {0, "foobarz"}}; float max = dictionary.Max(x => x.Key); //42 Stream<Map.Entry<K,V>> topTen = map.entrySet().stream()

我有一张
地图
,希望获得所有钥匙的最大值。在C#中,我会这样做:

var dictionary = new Dictionary<float, string>{{5,"foo"}, {42, "bar"}, {0, "foobarz"}};
float max = dictionary.Max(x => x.Key); //42
Stream<Map.Entry<K,V>> topTen = map.entrySet().stream()
                                   .sorted(Map.Entry.byKeyComparator().reversed())
                                   .limit(10);

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

接口
Stream
包含获取最大元素的方法
max
。您可以将方法引用用作
比较器
。方法
max
返回一个
Optional
,因为空流中没有最大元素。您可以使用方法
orElse
为这种情况提供替代值

float max = map.keySet().stream().max(Float::compareTo).orElse(0.0f);

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

Map.Entry<K,V> maxElt = map.entrySet().stream()
                           .max(Map.Entry.comparingByKey())
                           .orElse(...);
Map.Entry maxElt=Map.entrySet().stream()
.max(Map.Entry.comparingByKey())
.orElse(…);
这不仅允许获取最小/最大元素,还允许排序,因此很容易找到前十个键/值对,如下所示:

var dictionary = new Dictionary<float, string>{{5,"foo"}, {42, "bar"}, {0, "foobarz"}};
float max = dictionary.Max(x => x.Key); //42
Stream<Map.Entry<K,V>> topTen = map.entrySet().stream()
                                   .sorted(Map.Entry.byKeyComparator().reversed())
                                   .limit(10);
Stream topTen=map.entrySet().Stream()
.sorted(Map.Entry.byKeyComparator().reversed())
.限额(10);

Float
还包含
compare(x,y)
,因此您也可以使用
Float::compare
@Pshemo:True。但是,
compare
使用基本类型,而
compareTo
使用包装类型。在本例中,我更喜欢后者,因为代码已经在使用包装类型(即避免装箱/取消装箱)。取消装箱意味着
Float.compare(foo.floatValue(),bar.floatValue())
foo.compareTo(bar)
返回
Float.compare(this.value,bar.value)
。这意味着在第一种情况下,我们将调用
floatValue()
两次以获取
value
,而在第二种情况下,我们可以跳过它,因为我们可以直接访问
value
。谢谢,我今天学到了一些新东西:)@nosid你认为在练习中会有什么表现上的差异吗?我希望
floatValue()
的调用是内联的,一旦JIT完成,就会产生相同的代码。@MauriceNaftalin:不,我认为性能不是问题。我认为最好不要引入不必要的隐式类型转换。