由于我只是编程的初学者,所以这可能是一个琐碎的问题。 任务是为以下Junit测试用例编写代码,将数组的元素提升为三次方:
@Test
public void testCubeArray() {
FirstSteps firstSteps = new FirstSteps();
int[] array1 = {1, 2, 3, 0};
firstSteps.cube(array1);
int[] arrayResult1 = {1, 8, 27, 0};
assertArrayEquals(arrayResult1, array1);
int[] array2 = {100, 200, 3, 10};
firstSteps.cube(array2);
int[] arrayResult2 = {1000000, 8000000, 27, 1000};
assertArrayEquals(arrayResult2, array2);
}
我的代码就是这样public void cube(int[] array) {
for (int i = 0; i <= array.length; i++) {
int result = (int)Math.pow(i,3);
}
测试失败,结果为2,而不是8。我做错了什么?
答案 0 :(得分:1)
这里的问题很简单(不要怕答案太长,很有趣!)
firstSteps.cube(array1);
您要将数组实例传递给cube
方法,这很好。但是
public void cube(int[] array) {
for (int i = 0; i <= array.length; i++) {
int result = (int)Math.pow(i,3);
}
}
您没有触摸输入数组,甚至没有使用它。见
(int)Math.pow(i,3);
您要将计数器变量i
而不是pow
传递给array[i]
方法。
另外,您正在将pow
结果分配给有限范围的局部变量,这意味着result
变量将以新的初始值连续重新创建,但没有实际用处。
另一个问题在这里
i <= array.length
这将导致ArrayIndexOutOfBoundsException
,因为您将查找比array
中可用索引更大的索引。请记住,索引从0
开始!
例如,您可以将Math.pow
结果分配给原始数组
for (int i = 0; i < array.length; i++) {
array[i] = (int) Math.pow(array[i], 3);
}
由于您知道,数组是由refence传递的,因此其中的每个引用对象都会被更新。
现在,这个
int[] array1 = {1, 2, 3, 0};
firstSteps.cube(array1);
int[] arrayResult1 = {1, 8, 27, 0};
assertArrayEquals(arrayResult1, array1);
将起作用:)
OlivierGrégoire在评论中建议在修改输入数组之间添加一个中间步骤(这是您现在正在做的,通常不是一个好选择,因为它可能导致意外的结果副作用)并使用Stream
库。查看评论,并记住其逻辑与下面的Stream
解决方案相同,只是在功能上不同。
public int[] cube(final int[] array) {
// Initialize a new array, with the same size as the input one,
// to hold the computed value. We will return this array instead
// of modifying the inputted one.
final int[] powResult = new int[array.length];
for (int i = 0; i < array.length; i++) {
powResult[i] = (int) Math.pow(array[i], 3);
}
return powResult;
}
您现在可以将其用作
// We use array1 only as input
final int[] array1 = {1, 2, 3, 0};
final int[] powResult = firstSteps.cube(array1);
int[] arrayResult1 = {1, 8, 27, 0};
// We use the returned powResult for comparison,
// as array1 has not been touched.
assertArrayEquals(arrayResult1, powResult);
此外,我想向您介绍使用功能方法的版本。
public int[] cube(final int[] array) {
return IntStream.of(array)
.map(v -> (int) Math.pow(v, 3))
.toArray();
}
在这里,我们不触摸array
输入数组,但是我们使用Stream
创建了一个新的修改后的副本。那就是数组变成了int
流,我们可以检查该流的每个元素。
.map(v -> (int) Math.pow(v, 3))
如果继续进行编程,您可能会得出结论,该解决方案要好得多。
答案 1 :(得分:0)
这里有很多错误。首先,您既无法在cube
方法中创建任何数组,也无法返回和使用该数组,也无法更改现有数组。重写cube
方法的主体,如下所示:
public void cube(int[] array) {
for (int i = 0; i < array.length; i++) {
array[i] = (int) Math.pow(array[i], 3);
}
}
现在测试应通过如下:
int[] array2 = {100, 200, 3, 10};
firstSteps.cube(array2);
int[] expected = {1000000, 8000000, 27, 1000};
assertArrayEquals(expected, array2);
应类似地在测试中使用其他断言。