For-Each 循环 Java 错误 ArrayIndexOutOfBoundsException

Posted

技术标签:

【中文标题】For-Each 循环 Java 错误 ArrayIndexOutOfBoundsException【英文标题】:For-Each Loop Java Error ArrayIndexOutOfBoundsException 【发布时间】:2018-07-19 02:27:36 【问题描述】:

在我的程序中,我需要一个 for-each 循环来计算给定数组中偶数的数量,并为每个循环增加变量 even。当我使用标准的for 循环,即(i = 0; i < numbers.length; i++;) 时,代码可以正常工作。但是,我的作业要求我为这个特定问题使用 for-each 循环。我做错了吗?

int [] numbers = new int[8];
int even = 0;
int odd = 0;

for (int i = 0; i < numbers.length; i++)  
    numbers[i] = (int)(Math.random() * 51 + 50);


for (int i : numbers) 
    if (numbers[i] % 2 == 0) 
        even++;
    
    else
        odd++;

这会引发错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 54

【问题讨论】:

您已经使用 for-each 循环选择了每个项目,所以 if (i % 2 == 0) 就足够了。这里,i 是数组中的项目,而不是索引。 在第二个循环中,变量 i 表示精确值而不是索引 这是一个非常基本的错误! 【参考方案1】:
if (numbers[i] % 2 == 0) 

在你的 foreach 循环中,你不需要使用 index.html 来访问它。只需 i 就足够了,因为 foreach 继续在您正在使用的数组/集合中直接为您提供 element(而不是索引)。

if (i % 2 == 0) 

for (int i : numbers) 
        if (i % 2 == 0) 
            even++;
        
        else
            odd++;
        
  

您实际上可以通过检查第一个循环本身的偶数或奇数来完全消除第二个循环来缩短代码。

【讨论】:

那么在for-each循环中,它实际上引用的是值而不是数组中的位置? @MatthewThibodeau所以当你使用numbers[i]时,如果你的元素的值为2500,你指的是numbers[2500] 您不认为这与 Dheeraj Joshi 的上述答案相同。我看不出两次给出相同答案的价值。 @AdeshKumar 我没有复制。您应该检查过答案的时间戳。据我所知,我是第一个回答者。 哦!所以不是这样。对不起这是我的错!尽管如此,上面的答案应该会消失。【参考方案2】:

对于您案例中的每个循环,将解释如下:

for (int i : numbers)

数组numbers中的每一个整数都会被一个一个的放入i

所以,你做错的是:

if (numbers[i] % 2 == 0)

for (int i : numbers) 
if (numbers[i] % 2 == 0) 
even++;

else 
odd++;
 

i 不会像传统的 for 循环那样增加 evrytime 循环进行,这里 i 携带 实际值

所以你应该从 numbers[i]%2==0 更改为 i%2==0

 for (int i : numbers) 
if (i % 2 == 0) 
    even++;

else 
    odd++;
  

【讨论】:

【参考方案3】:

i 是数字本身,而不是索引。所以你应该:

for (int i : numbers) 
    if (i % 2 == 0)  // <-- use i not numbers[i]
        even++;
    
    else 
        odd++;
    

【讨论】:

【参考方案4】:

在 for Each 循环中无需提供数字[i],因此请使用以下代码。 对于 (int i : numbers) ,int i 是数组中存在的数字。所以只需将条件放在数字本身上。如果你使用 number[i] 那么它将检查第 i 个索引的值,如果任何数字大于你的数组大小,它将抛出 ArrayOutOfBox 异常。

 int [] numbers = new int[8];
        int even = 0;
        int odd = 0;

        for (int i = 0; i < numbers.length; i++)  
            numbers[i] = (int)(Math.random() * 51 + 50);
        

    for (int i : numbers) 
            if (i % 2 == 0) 
                even++;
            
            else
                odd++;

【讨论】:

【参考方案5】:

虽然有很多答案。您也可以通过使用 java-8 流来实现相同的目的。使用reducer找出偶数,然后从长度减少偶数得到奇数。

见下面的代码:-

   int[] numbers = new int[8];

    for (int i = 0; i < numbers.length; i++) 
        numbers[i] = (int) (Math.random() * 51 + 50);
    

    int even = Arrays.stream(numbers)
            .reduce(0, (a, b) -> 
                a += b % 2 == 0 ? 1 : 0;
                return a;
            );
    int odd = numbers.length - even;

【讨论】:

虽然 +1 可以很好地使用减速器,并且无需任何计算即可获得赔率的逻辑。尽管您也应该尝试使用 Int 流来创建数组。 我认为这个问题的重点是计算偶数和赔率。我会在处理完之后编辑我的答案【参考方案6】:

if (numbers[i] % 2 == 0) 中替换numbers[i],只需输入i

for (int i : numbers) 中的i 实际上存储数组(numbers) 中从0th 索引到数组的length 的元素。

if (numbers[i] % 2 == 0) 中,numbers[i] 将为您提供ith 索引处的元素。而i 的值是来自(int)(Math.random() * 51 + 50) 的某个随机数,它将始终是大于50number。所以你要做的是访问一些超出你声明的数组大小范围的元素,即int [] numbers = new int[8]中的8

【讨论】:

以上是关于For-Each 循环 Java 错误 ArrayIndexOutOfBoundsException的主要内容,如果未能解决你的问题,请参考以下文章

2017.4.13 Java 增强型的for循环 for each

2优先使用for-each循环

反编译看java for-each循环

从字节码看Java中for-each循环(增强for循环)实现原理

为啥 for-each 循环适用于数组? (爪哇)

如何将 for-each 循环应用于字符串中的每个字符?