我是java8 stream&的新手抱歉这个愚蠢的问题。这是我的代码,我正在尝试创建一个id&值,但我收到此错误,无法修复。任何人都可以帮助我什么是替代方案?
public static Map<Integer, String> findIdMaxValue(){
Map<Integer, Map<String, Integer>> attrIdAttrValueCountMap = new HashMap<>();
Map<Integer, String> attrIdMaxValueMap = new HashMap<>();
attrIdAttrValueCountMap.forEach((attrId, attrValueCountMap) -> {
attrValueCountMap.entrySet().stream().sorted(this::compareAttrValueCountEntry).findFirst().ifPresent(e -> {
attrIdMaxValueMap.put(attrId, e.getKey());
});
});
}
和排序方法
public static int compareAttrValueCountEntry(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
int diff = e1.getValue() - e2.getValue();
if (diff != 0) {
return -diff;
}
return e1.getKey().compareTo(e2.getKey());
}
我收到此错误
"Cannot use this in a static context"
答案 0 :(得分:2)
由于方法compareAttrValueCountEntry
被声明为静态,
替换方法参考
this::compareAttrValueCountEntry
与
<Yourclass>::compareAttrValueCountEntry
答案 1 :(得分:1)
您的代码存在一些问题。虽然this::compareAttrValueCountEntry
很容易
通过将其更改为ContainingClassName::compareAttrValueCountEntry
进行修复,此方法是不必要的
因为有几种工厂方法,如Map.Entry.comparingByKey
,Map.Entry.comparingByValue
,
Comparator.reversed
和Comparator.thenComparing
,可以合并以实现相同的目标
这可以保护您免受compareAttrValueCountEntry
内的错误的影响。比较int
很有吸引力
减去值,但这很容易出错,因为两个int
值之间的差异并不总是如此
适合int
范围,因此可能发生溢出。此外,否定撤销订单的结果是
因为价值可能是Integer.MIN_VALUE
而没有正面的对应物,因此,否定它
将溢出回Integer.MIN_VALUE
而不是更改符号。
您可以使用更清晰的流操作生成,而不是通过forEach
循环添加到另一个地图
地图,您可以将sorted(…).findFirst()
简化为min(…)
,这不仅更短,而且更简单
可能更便宜的操作。
把它放在一起,我们得到
Map<Integer, String> attrIdMaxValueMap =
attrIdAttrValueCountMap.entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().entrySet().stream()
.min(Map.Entry.<String, Integer>comparingByValue().reversed()
.thenComparing(Map.Entry.comparingByKey())).get().getKey()));
请注意,我在前面添加filter
操作,拒绝空地图,这样可以确保始终存在
匹配元素,因此无需处理ifPresent
或类似的问题。相反,Optional.get
可以无条件地被召唤。
由于此方法称为findIdMaxValue
,因此可能需要通过调用max
来反映该方法
在流上而不是min
,这只是反转哪个比较器的问题:
Map<Integer, String> attrIdMaxValueMap =
attrIdAttrValueCountMap.entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().entrySet().stream()
.max(Map.Entry.<String, Integer>comparingByValue()
.thenComparing(Map.Entry.comparingByKey(Comparator.reverseOrder())))
.get().getKey()));
不幸的是,这样的结构遇到了类型推断的局限性,这需要我们,
使用嵌套构造(如Map.Entry.comparingByKey(Comparator.reverseOrder())
而不是。{
Map.Entry.comparingByKey().reversed()
)或插入显式类型,例如
Map.Entry.<String, Integer>comparingByValue()
。在第二个变体中,反转第二个比较器,
我们两次点击了... ...
在这种特定情况下,创建比较器只需要一次,将其保存在变量中并在流操作中重用它:
Comparator<Map.Entry<String, Integer>> valueOrMinKey
= Map.Entry.<String, Integer>comparingByValue()
.thenComparing(Map.Entry.comparingByKey(Comparator.reverseOrder()));
Map<Integer, String> attrIdMaxValueMap =
attrIdAttrValueCountMap.entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().entrySet().stream().max(valueOrMinKey).get().getKey()));