【问题标题】:for loop behaving differently in java [duplicate]java中的for循环行为不同[重复]
【发布时间】:2017-12-24 18:54:52
【问题描述】:
class A {
public static void main (String[] args) {
   // code ...
   System.out.println(B.fun1());
   // code ...
}

class B {
   // code ...
   public int fun1(){
   return C.fun2();
 }

class C {
    // code ...
    public int fun2() {
        int u = 0;
        for(int k= 0; arr[k] != null ; k++,System.out.println("k="+k)) {
            int a = arr[k].getVal();
            String s = Integer.toString(a);
            if (s.equals(("1"))) {
                u = u + 10;
            } else {
                u = u + a;
            }
        }
        return u;
    }
 }

我有一个与上面所示结构相同的代码,当main 执行时输出是:

k=1
k=2
k=3

fun1 中打印在main 中的返回值u 是:

30  //depends on getVal()

但是在这个输出之后它也显示了这个

k=1
k=2
k=1
k=2
k=1
k=2

我收到了ArrayIndexOutOfBoundsException。这怎么可能? 我的问题是为什么我得到这个 k=1 k=2 k=1 ... 东西 代码:https://drive.google.com/open?id=1aZYv7qqYd1___fXA92lbtLO5WccI9wz6 如何重现:事情是随机的,所以尝试玩几次。

【问题讨论】:

  • 请创建一个minimal reproducible example,我们可以运行它来复制问题。
  • 可能是因为arr[k] != null
  • arr[k] != null 带有超出范围的索引会在大多数语言中导致错误,因为您必须先获取 arr[k] 才能进行比较。如果 k 索引超出范围则错误。
  • 正如@AniketSahrawat 提到的,您没有检查是否超出了for(..; arr[k] != null; ...) 中的数组限制。是什么阻止 k 超出数组的大小?尝试检查您是否达到数组长度for(...; k < arr.length; ...)
  • 就像 arr[0]=null; arr[1]=null;... 当我调用它时,它会像 arr[0]=10;arr[1]=7;arr[2]=null,arr[3]=null... 和 i还尝试将 k 限制为数组大小的最大值,例如 ..for(int k= 0; arr[k] != null && k

标签: java for-loop output


【解决方案1】:
for(int k= 0; arr[k] != null ; k++,System.out.println("k="+k)) {

您对 k 可以达到多高没有任何限制,而您只是在评估直到发现它为空。超出索引值将引发 IndexOutOfBoundsException 而不是评估为空值,因此如果您的数组中没有空值,您将始终遇到异常,除非以其他方式中断循环。为了避免这种情况,您可以在进行空值检查之前检查以确保 k 在数组长度内。

for(int k= 0; k < arr.length && arr[k] != null ; k++,System.out.println("k="+k)) {

【讨论】:

  • 我知道,而且我在之前的 cmets 中说过很多次都没有用
  • 那么您还必须在循环定义之外修改 k ,导致它以不寻常的方式运行。这确实不是值得推荐的做法。
  • 它是一个局部变量
  • 这个变量仍然可以在循环体中修改。无论如何,如果您在循环定义中对数组长度有适当的约束,那么您永远不应该在该行上遇到越界异常。您的结果 {1, 2, 1, 2, ...} 表示修改索引跟踪值或连续多次运行的循环 - 在这种情况下,这很可能是显而易见的问题:您的几个数组之一不包含空值,因此不会正确终止您的循环之一。同样,通过适当的循环约束,这应该是完全可以避免的。
  • 代码已经出来了为什么不自己检查一下。 :-)
【解决方案2】:

原代码为here

查看您的整个代码,我猜想如何删除控制台输出中的多余数字,我还进行了一些更改以使您的代码更有效率。让我知道这是否是您问题的最终解决方案。

首先,我删除了循环内的System.out.Println(k),从而消除了控制台输出中最后的额外数字:

public int evaluateHand() {
    int u = 0;
    try {
        for(int k= 0; hand[k] != null; k++) {
            int a = hand[k].getRank();
            String ok = Integer.toString(a);
            if (ok.equals(("13"))) {
                u = u + 10;
            }else if (ok.equals(("12"))) {
                u = u + 10;
            } else if (ok.equals(("11"))) {
                u = u + 10;
            } else if (ok.equals(("1"))) {
                u = u + 11;
            } else {
                u = u + a;
            }
        }

【讨论】:

猜你喜欢
  • 2014-01-12
  • 2021-03-02
  • 2021-02-13
  • 2017-04-03
  • 2014-11-03
  • 1970-01-01
  • 1970-01-01
  • 2021-06-15
  • 2023-03-31
相关资源
最近更新 更多