Java – 可变参数 | While(true) | Scanner – 退出无限循环

huangapple go评论81阅读模式
英文:

Java - Varargs|While(true)|Scanner - exiting infinite while loop

问题

在描述我的问题之前,我想让您知道我熟悉ArrayList,但我想知道它如何与varargs一起使用。

我的问题是:
当我在使用varargs与scanner输入时,无法通过输入值零(变量类型为int)退出无限循环。

我尝试过:
尝试通过简单的“如果输入数字== 0 --> 从循环中断”来退出无限循环。我不明白为什么这行不通。我应该在代码上做什么改变?

我尝试过的一些代码:

static Scanner scanner = new Scanner(System.in);

public static void main(String[] args) {
    createIntArray();
}

public static void createIntArray(int... numbers) {
    System.out.println("Enter numbers:");
    while (true) {
        for (int i = 0; i < numbers.length; i++) {
            numbers[i] = scanner.nextInt();
            if (numbers[i] == 0) {
                break;
            }
        }
    }
}

向我的问题添加一些背景信息:
我读过一本关于Java的书,在关于一维数组的课程结束时,有一个未解决的练习问题,涉及读取1-100之间的整数并计算出现的次数。输入应以0结尾。因此,数组的长度未定义。在关于一维数组的课程中,varargs被描述为具有可变数量参数的数组。我理解参数的数量未确定。我在想是否可以使用varargs通过Scanner方法创建具有未定义长度的数组。
现在知道varargs创建的数组的初始长度为零,我不确定如果我想使用Scanner方法来增加数组的长度,该如何操作。
我知道ArrayList更灵活,可以用来解决这个问题,但是在一维数组课程的最后有一个问题,其中一个任务是创建一个未定义长度的数组,这让我觉得这也可以用一维数组来实现。

英文:

Before describing my issue, I would like to let you know that I am familiar with ArrayList, but I am curious how this works with varargs.

My problem is:
I can not exit the infinite loop with the input value zero (variable type is int) when I use varargs with scanner input.

I've tried:
to exit the infinite loop with a simple "if the input number == 0 --> break from the loop". I don't understand why this doesn't work. What should I change on the code?

Some code I've tried:

static Scanner scanner = new Scanner(System.in);

public static void main(String[] args) {
    createIntArray();
}

public static void createIntArray(int... numbers) {
    System.out.println(&quot;Enter numbers:&quot;);
        while (true) {
            for (int i = 0; i &lt; numbers.length; i++) {
                numbers[i] = scanner.nextInt();
                if (numbers[i] == 0) {
                    break;
                }
            }
    }
}

Adding some more background information to my question:
I read a Java book where the lesson about single dimensional arrays ends with an unsolved exercise question about reading the integers between 1-100 and counting the occurrences. The input should end with 0. Thus, the arrays length is not defined. In the single dimensional arrays lesson the varargs is described as an array with variable number of arguments. I understand that the number of arguments is not set. I was thinking I could use varargs to create array with undefined length using the Scanner method.
Now knowing that the initial length of the array created by the varargs is zero, I am not sure where the length could be manipulated if I would like to use the Scanner method to increase the arrays length.
I know that ArrayList is more flexible and could be use to solve this problem, but having a question at the end of the single dimensional arrays lesson where one of the task is to create undefined length array makes me thing this could be done with a single dimensional array too.

答案1

得分: 1

Your problem has nothing to do with varargs (also known as "variable arity methods").

Your problem is that, in:

static Scanner scanner = new Scanner(System.in);

public static void main(String[] args) {
    createIntArray();
}

public static void createIntArray(int... numbers) {
    System.out.println("Enter numbers:");

    while (true) {
        for (int i = 0; i < numbers.length; i++) {
            numbers[i] = scanner.nextInt();
            if (numbers[i] == 0) {
                break;
            }
        }
    }
}

the for loop is never entered, and therefore, you never break out from the while.

The reason why the for loop's body is never executed is that i < numbers.length always evaluates to 0 < 0, which is false. So, your while loop goes on infinitely, without ever entering the for.


Varargs (variable arity method)

You do not ask the question that might (I think - it perfectly well may) attract more attention:

  • Why does my code compile?

But you do mention "varargs," and I will use this chance to provide you with more details on that topic.

Type...varargs and Type[] varargs compile to the same code.

There is a little syntactical catch though:

OCP Java SE 8 Preparation text-book (Scott Selikoff, Jeanne Boyarsky):
>Invocation of the method with a variable length parameter should happen with literally a variable number of elements [0..n]. In contrast, the invocation of a method with an array type parameter must happen by providing an array as an argument.

Effective Java, 3rd Edition (by Joshua Bloch):
>The varargs facility works by first creating an array whose size is the number of arguments passed at the call site. Then, it puts the argument values into the array and finally passes the array to the method.

That is why your code compiles. If you have a Type...varargs parameter in your method, you can omit the corresponding explicit argument entirely (as you are doing). The corresponding value, as defined above, will be assigned implicitly to that parameter.

英文:

Your problem has nothing to do with varargs (aslo known as "variable arity methods").

Your problem is that, in:

static Scanner scanner = new Scanner(System.in);

public static void main(String[] args) {
    createIntArray();
}

public static void createIntArray(int... numbers) {
    System.out.println(&quot;Enter numbers:&quot;);
    
    while (true) {
        for (int i = 0; i &lt; numbers.length; i++) {
            numbers[i] = scanner.nextInt();
            if (numbers[i] == 0) {
                break;
            }
        }
    }
}

the for loop is never entered, and therefore, you never break out from the while.

The reason why for loop's body is never executed is, that i &lt; numbers.length always evaluates to 0 &lt; 0, which is false. So, your while loop goes on infinitely, with never entering into the for.


Varargs (variable arity method)

You do not ask the question, which might (I think - it perfectly well may) strike more attention:

  • Why does my code compile?

but you do mention "varargs", and I will use this chance to let you know a bit more details on that topic.

Type...varargs and Type[] varargs compile to the same code.

There is a little syntactical catch though:

OCP Java SE 8 Preparation text-book (Scott Selikoff, Jeanne Boyarsky):
>Invocation of the method with variable length parameter should happen with literally - variable number of elements [0..n], whereas invocation of the method of array type parameter, must happen by providing an array as an argument.

Effective Java, 3rd Edition (by Joshua Bloch):
>The varargs facility works by first creating an array whose size is the number of arguments passed at the call site, then putting the argument values into the array, and finally passing the array to the method.

That is why your code compiles. If you have Type...varargs parameter in your method, you can omit the corresponding explicit argument at all (that is what you are doing), and the corresponding (to above definitions) implicit value will be assigned to that parameter.

答案2

得分: 0

你隐式地将一个空数组传递给了 createIntArray 方法。因此,for 循环不会执行(因为 numbers.length0),并且 break 语句永远不会被执行。

你可以改为从方法中返回一个数组,而不是将数组传递给该方法:

public static void main(String[] args) {
    int[] numbers = createIntArray();
}

public static int[] createIntArray() {
    System.out.println("输入数字:");
    List<Integer> list = new LinkedList<>();
    while (true) {
        int num = scanner.nextInt();
        if (num == 0) {
            break;
        }
        list.add(num);
    }
    return list.stream().mapToInt(Integer::intValue).toArray();
}
英文:

You're implicitly passing an empty array to createIntArray. Therefore, the for loop doesn't execute (because numbers.length is 0), and the break statement is never reached.

Instead of passing an array to the method, you could return one from it:

public static void main(String[] args) {
    int[] numbers = createIntArray();
}

public static int[] createIntArray() {
    System.out.println(&quot;Enter numbers:&quot;);
    List&lt;Integer&gt; list = new LinkedList&lt;&gt;();
    while (true) {
        int num = scanner.nextInt();
        if (num == 0) {
            break;
        }
        list.add(num);
    }
    return list.stream().mapToInt(Integer::intValue).toArray();
}

huangapple
  • 本文由 发表于 2020年9月26日 23:57:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/64079704.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定