for / break比iterator()更有效.next()?

时间:2014-07-16 21:46:48

标签: java foreach break

众所周知,mapX中只有一个条目。代码量度工具抱怨使用' break'在for循环中,但通常,在如此小的循环中,我让它通过。在这种情况下,虽然知道只有一个条目,但我不确定哪个更有效。

那么,当您知道地图只包含一个元素时,以下哪项更有效?

可能的替代品:

Map.Entry<String,String> e = mapX.entrySet().iterator().next();
Y.setMsg(e.getValue());
Y.setMsgKey(e.getKey());

原始代码:

for (String key : mapX.keySet()){
    Y.setMsg(mapX.get(key));
    Y.setMsgKey(key);
    break;
}

3 个答案:

答案 0 :(得分:4)

第一个版本比第二个版本快(使用“for”loop /“break”):

  1. 循环版本必须在调用hasNext()之前调用next()
  2. 循环版本是迭代keySet而不是entryset,因此必须进行额外的map查找才能获得相应的值。
  3. 循环版本可能在break处有一个额外的分支指令......尽管这很小,可能会被JIT编译器优化掉。
  4. 但使用第一个版本(IMO)的最佳理由是代码更容易理解/更简单。 (代码度量工具在这种情况下很有用......)


    当然,另一方面是如果映射为空,则代码的非循环版本将引发异常。如果你需要处理“空地图”的情况,你应该这样写:

    if (!mapX.isEmpty()) {
        Map.Entry<String,String> e = mapX.entrySet().iterator().next();
        y.setMsg(e.getValue());
        y.setMsgKey(e.getKey());
    }
    

答案 1 :(得分:0)

就个人而言,我发现第一个变体更简洁。如果你正在使用guava,你也可以这样写:

Map.Entry<String,String> e = Iterables.getOnlyElement(mapX.entrySet());

答案 2 :(得分:0)

Map.Entry<String,String> e = mapX.entrySet().iterator().next();
Y.setMsg(e.getValue());
Y.setMsgKey(e.getKey());

相同
for (String key : mapX.keySet()){
    Y.setMsg(mapX.get(key));
    Y.setMsgKey(key);
    break;
}

有一个例外:循环首先在迭代器上调用hasNext()

前者更强烈地暗示只有一个元素(至少只有一个你感兴趣的元素)。后者说&#34;我将循环遍历所有元素......除了我将在第一个元素之后停止。&#34;如果你不循环,为什么要使用循环?

似乎非循环版本就是这样。