如何在Collectors.groupBy中集成敲击逻辑并修改统计值
用Stream/Collector重写钉子敲击问题的实现
问题场景
有一块钉了钉子的木板,钉子初始长度相同,已按钉入木板的深度排序。给定可敲击的钉子数量N(敲击会让钉子更深入木板),需要返回深度相同的钉子的最大子集大小。
示例说明
示例钉子深度序列:
1 1 2 3 3 4 4 4 4 4 5 5 10 --------------------------
- 当N=3时,将深度为5和10的钉子敲下去,可得到8个深度为4的外露钉子;
- 当N=8时,将深度为3之后的所有钉子敲下去,最终能得到10个深度相同的钉子。
现有实现思路
多数解答未使用Collectors,我通过groupBy收集器得到了一个以钉子深度为键、对应数量为值的Map,示例如下:
1 2 2 1 3 2 4 5 5 2 10 1
实现分组的代码:
Map<Integer, Long> grouped = nails.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
之后我遍历Map的entrySet流来应用敲击逻辑:
return grouped.entrySet().stream().map(e -> e.getValue().intValue() + Math.min(toHit , size - (nails.indexOf(e.getKey()) + e.getValue().intValue()))) .max(Integer::compare).get();
其中toHit为可敲击的钉子数量N,size为木板上的总钉子数。
遇到的困惑
我希望将“敲击”逻辑直接集成到groupBy语句中,但在Collectors的Lambda写法上遇到了问题:
- 如何为统计值添加额外的数值?
- 如何访问分组时用作键的标识值?
内容的提问来源于stack exchange,提问作者dr jerry
相关产品推荐
相关产品推荐

