Java 循环Foreach的性能差异

Java 循环Foreach的性能差异,java,Java,我总是问自己“使用什么”应该使用for循环还是foreach。 在我看来,两者都是“相同的”。我知道通过列表等进行迭代是一种更好的方法,但如果我们有以下情况会怎么样: for (String zipCode : zipCodes) { if (zipCode.equals(zip)) { return true; } } 或 for(int i=0;i

我总是问自己“使用什么”应该使用for循环还是foreach。 在我看来,两者都是“相同的”。我知道通过列表等进行迭代是一种更好的方法,但如果我们有以下情况会怎么样:

for (String zipCode : zipCodes) {
    if (zipCode.equals(zip)) {
        return true;
    }
}

for(int i=0;i

什么会更好?或者在这种情况下真的没有区别吗?

如果
zipCodes[i]
不是O(1),那么第二种情况的性能会差得多。(也就是说,我认为Java中还不存在一个容器,
[]
不是O(1))。换句话说,缩写形式的
for
循环不能再慢了


另外,
循环的缩写形式
更清晰,除非速度很重要,否则这确实应该是首要考虑因素。

如果
zipCodes[i]
不是O(1),那么第二种情况的性能会差得多。(也就是说,我认为Java中还不存在一个容器,
[]
不是O(1))。换句话说,缩写形式的
for
循环不能再慢了


另外,
循环的缩写形式
更加清晰,除非速度很重要,否则这确实应该是首要考虑因素。

现在的优化不太重要,因为任何差异都不会明显,除非您需要处理大量数据。此外,如果使用集合,则性能将取决于所选的实现

您真正应该考虑的是代码的质量。规则是,您应该使用尽可能少的元素来尽可能清晰地呈现逻辑。第二个解决方案引入了一个新元素,i索引,它实际上并不需要,只会使代码变得更复杂一点。只有在每次迭代中确实需要知道索引时才使用fori循环


因此,从代码质量的角度来看,您应该使用第一种解决方案:-)

如今,优化已不再那么重要,因为任何差异都不会被察觉,除非您需要处理大量数据。此外,如果使用集合,则性能将取决于所选的实现

您真正应该考虑的是代码的质量。规则是,您应该使用尽可能少的元素来尽可能清晰地呈现逻辑。第二个解决方案引入了一个新元素,i索引,它实际上并不需要,只会使代码变得更复杂一点。只有在每次迭代中确实需要知道索引时才使用fori循环

因此,从代码质量的角度来看,您应该使用第一种解决方案:-)

请注意,使用for each循环没有性能损失, 甚至对于阵列也是如此。事实上,它可能会提供一点性能优势 在某些情况下,当它计算 数组索引的限制仅为一次

约书亚·布洛赫的《有效Java》第46项

请注意,使用for each循环没有性能损失, 甚至对于阵列也是如此。事实上,它可能会提供一点性能优势 在某些情况下,当它计算 数组索引的限制仅为一次


Joshua Bloch的《高效Java》中的第46项哪一项更具可读性?至于性能,您自己也可以尝试一下,在这种特定情况下,
zipCodes.contains(zip)
将是最好的。我不得不说,这是一个数组,我确实可以将其转换为列表,但这将是低效的。第一种情况更具可读性,在我看来,哪种更具可读性?至于性能-自己试试看,在这种特定情况下,
zipCodes.contains(zip)
将是最好的选择。我不得不说,这是一个数组,我确实可以将其转换为列表,但这将是低效的。更具可读性的是第一种情况,在我看来,必须为那些不知道的人澄清:
O(1)
意味着算法不依赖于元素的数量。这与
O(n)
相反,在后者中,添加的元素越多,算法所需的时间就成比例地越长。请参阅:为那些不知道的人澄清:
O(1)
表示算法不依赖于元素的数量。这与
O(n)
相反,在后者中,添加的元素越多,算法所需的时间就成比例地越长。请参阅:
只计算一次数组索引的限制。
这是过时的,所有计数的循环都会接受JIT优化,并且以数组大小为边界的循环会作为例行程序删除索引检查。
只计算一次数组索引的限制。
这是过时的,所有计数的循环都会接受JIT优化,并且数组大小限制的循环会作为例行程序删除索引检查。
for (int i = 0; i < zipCodes.length; i++) {
    if (zipCodes[i].equals(zip)) {
        return true;
    }
}