基于HashMap的Java8性能

基于HashMap的Java8性能,java,java-8,java-stream,Java,Java 8,Java Stream,我试图解决的问题是MapSum。 简而言之,任务是对键上的值求和 迭代映射=117 ms: Iterator<Entry<String, Integer>> it = _map.entrySet().iterator(); int count = 0; while(it.hasNext()) { Entry<String, Integer> entry = it.next();

我试图解决的问题是
MapSum
。 简而言之,任务是对键上的值求和

迭代映射=117 ms

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; 
             }   
        }
问题

int count = _map.keySet().stream()
                .filter(key -> key.startsWith(prefix))
                .map(str -> _map.get(str))
                .mapToInt(Number::intValue)
                .sum();

  • 您是否应该避免可能使用for循环的流

或者我是否以非流式方式编写了上述代码

您的流式版本每项都有一个额外的
get
,速度可能不如您想象的快。试着这样做:

int count = _map.entrySet().stream()
                .filter(ent-> ent.getKey().startsWith(prefix))
                .mapToInt(ent -> ent.getValue().intValue())
                .sum();
当然,在Java中正确地进行微基准测试也不是那么容易,因此您的测量可能会出错

但是,最后,流通常不是写东西的最快方式。在大多数情况下,性能损失很小,语法可能比备选方案更清晰


编辑:回答您的最后一个问题——流通常是惰性地进行评估的。最后一步将项目拉过前面的所有步骤

您可以浏览的几个链接中的一个“什么是Java流的理想用例?”太宽泛了“您应该避免可能使用for循环的流吗?”没有“Java 8评估是懒惰的还是急切的?”什么?我不知道您是如何对其进行基准测试的,但这两个代码段都有所不同。在stream one中,您只对键集进行迭代,这意味着您必须为每个键调用get(例如,如果您使用的是hashmap,则意味着重新计算哈希,这会增加额外的时间)。一个更公平的比较是做
\u map.entrySet().stream().filter(e->e.getKey().startsWith(prefix)).map(map.Entry::getValue).mapToInt(Number::intValue).sum()@AlexisC。我同意这种比较并不完全公平。我感兴趣的是,对于给定的任务,我应该在什么时候使用Java 8,或者我以错误的方式使用流等等。如果流是惰性排序的,我希望流速度至少比传统的for循环快,而不是慢of@AlexisC:可以做得更短:
\u map.entrySet().stream().filter(e->e.getKey().startsWith(prefix)).mapToInt(Map.Entry::getValue).sum();
不需要显式调用
.intValue()
。您可以简单地说
.mapToInt(ent->ent.getValue())
甚至
.mapToInt(Map.Entry::getValue)