问题描述
在描述我的问题之前,我想告诉您我熟悉ArrayList,但是我很好奇这与varargs一起工作的方式。
我的问题是: 当我在扫描仪输入中使用varargs时,输入值为零(变量类型为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使用Scanner方法创建具有不确定长度的数组。 现在知道由varargs创建的数组的初始长度为零,如果我想使用Scanner方法来增加数组的长度,我不确定在哪里可以操纵该长度。 我知道ArrayList更加灵活,可以用来解决此问题,但是在一维数组课程的最后有一个问题,其中一项任务是创建未定义长度的数组,这使我可以用一个维数组。
解决方法
您的问题
您的问题与varargs(也称为“可变Arity方法”)无关。
您的问题在于,
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;
}
}
}
}
for loop
从未输入,因此,您永远不会脱离while
。
for loop
的主体从未被执行的原因是,i < numbers.length
始终求值为0 < 0
,即false
。因此,您的while
循环无限地进行 。
变量(可变Arity方法)
您不要问这个问题,这可能(我认为-可能很好)会引起更多关注:
- 为什么我的代码会编译?
但是您确实提到“ varargs”,我将借此机会让您了解有关该主题的更多细节。
Type...varargs
和Type[] varargs
编译为相同的代码。
尽管有一点语法上的收获:
OCP Java SE 8 Preparation text-book(斯科特·塞里科夫,珍妮·博雅斯基):
具有可变长度参数的方法的调用应按字面意义进行-元素数量[0..n]可变,而必须通过提供一个数组作为参数来调用数组类型参数的方法。
Effective Java,3rd Edition(由Joshua Bloch撰写):
varargs工具的工作方式是首先创建一个数组,该数组的大小是在调用站点传递的参数数量,然后将参数值放入数组,最后将数组传递给方法。
这就是为什么您的代码会编译的原因。如果您的方法中有Type...varargs
参数,则可以完全忽略(即您正在执行的操作),并且相应的(按上述定义)隐式值为分配给该参数。
您正在将一个空数组隐式传递给createIntArray
。因此,for
循环不会执行(因为numbers.length
是0
),并且决不会到达break语句。
您可以从其中返回一个数组,而不是将数组传递给该方法:
public static void main(String[] args) {
int[] numbers = createIntArray();
}
public static int[] createIntArray() {
System.out.println("Enter numbers:");
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();
}