我试图解决的问题是 MapSum
LeetCode Description 。
简而言之,任务是对键上的值求和。
迭代映射 = 117 毫秒:
Iterator<Entry<String, Integer>> it = _map.entrySet().iterator();
int count = 0;
while(it.hasNext()) {
Entry<String, Integer> entry = it.next();
String key = entry.getKey();
int val = entry.getValue();
if(key.startsWith(prefix)) {
count += val;
}
}
使用 Java 8 流 - 134 毫秒
int count = _map.keySet().stream()
.filter(key -> key.startsWith(prefix))
.map(str -> _map.get(str))
.mapToInt(Number::intValue)
.sum();
问题
- 您应该避免使用可能存在 for 循环的 Stream 吗?
或者我把上面的代码写在 non-streaming
中方式
最佳答案
您的流版本每个项目都有一个额外的 get
,这并不像您想象的那么快。尝试这样:
int count = _map.entrySet().stream()
.filter(ent-> ent.getKey().startsWith(prefix))
.mapToInt(ent -> ent.getValue().intValue())
.sum();
此外,当然,在 Java 中正确进行微基准测试并不那么容易,因此您的测量可能会出现偏差。
但是,最后,流通常不是最快的编写方式。在大多数情况下,性能损失相当小,并且语法比替代方案清晰得多。
编辑:回答你的最后一个问题——流通常是惰性评估的。最后一步将通过前面的所有步骤提取项目。
关于Java 8 相对于 HashMap 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46344201/