Java冒泡排序循环数组元素消失及JUnit测试异常问题求助
问题描述
我不是Java新手,但用JUnit测试时碰到两个问题:
- 用冒泡排序对数组排序时,循环里最后两个元素莫名消失,控制台没报
ArrayIndexOutOfBounds异常,只是数组大小变了、元素丢了 - 测试类只有两个测试方法,但运行时会识别出额外方法并报错
以下是相关代码和控制台输出:
排序类代码
package exercise5; public class Ejercicio5 { public static int[] sort(int[] arrayNums) { // array that I have tried: {6,5,8,3,7,1}; [6] System.out.println("size: " + arrayNums.length); for (int j = 0; j < arrayNums.length; j++) { System.out.println("j:" + j); if (arrayNums[j] > arrayNums[j + 1]) { System.out.println("entra"); int numGuardado = arrayNums[j + 1]; arrayNums[j + 1] = arrayNums[j]; arrayNums[j] = numGuardado; } print(arrayNums); } return arrayNums; } public static void print(int[] arrayParaImprimir) { System.out.println("Array:"); for (int j = 0; j < arrayParaImprimir.length; j++) { if (j != arrayParaImprimir.length - 1) { System.out.print(arrayParaImprimir[j] + ", "); } else { System.out.print(arrayParaImprimir[j] + "\n"); } } } }
JUnit测试类代码
package exercise5; import org.junit.Assert; import org.junit.jupiter.api.Test; import junit.framework.TestCase; public class Ejercicio5Test extends TestCase{ @Test public void resultadoCorrecto(){ int[] correct = {1,3,5,6,7,8}; int[] array = {6,5,8,3,7,1}; int[] result = Ejercicio5.sort(array); Assert.assertArrayEquals(result, correct); } @Test public void resultadoIncorrecto(){ int[] correct = {1,3,5,6}; int[] array = {3,5,6,1}; int[] result = Ejercicio5.sort(array); Assert.assertArrayEquals(result, correct); } }
控制台输出
size: 6 j:0 entra Array: 5, 6, 8, 3, 7, 1 j:1 Array: 5, 6, 8, 3, 7, 1 j:2 entra Array: 5, 6, 3, 8, 7, 1 j:3 entra Array: 5, 6, 3, 7, 8, 1 j:4 entra Array: 5, 6, 3, 7, 1, 8 j:5 size: 4 j:0 Array: 3, 5, 6, 1 j:1 Array: 3, 5, 6, 1 j:2 entra Array: 3, 5, 1, 6 j:3
问题解决方案
1. 冒泡排序元素消失的问题
排序方法存在两个核心错误:
- 循环条件
j < arrayNums.length会让j走到数组最后一个索引(比如长度为6时j=5),此时访问arrayNums[j+1]属于数组越界。虽然控制台没打印异常栈,但第一个测试实际已崩溃,JUnit框架捕获异常后直接执行第二个测试,你看到的"元素消失"是第二个测试的正常输出,并非第一个测试数组真的变小。 - 冒泡排序需要两层循环:外层控制排序轮数,内层做相邻元素比较交换,当前仅一层循环无法完成完整排序。
修复后的排序方法:
public static int[] sort(int[] arrayNums) { System.out.println("size: " + arrayNums.length); // 外层循环控制排序轮数,每轮将最大元素"冒"到未排序部分末尾 for (int i = 0; i < arrayNums.length - 1; i++) { // 内层循环仅比较到未排序部分的倒数第二个元素 for (int j = 0; j < arrayNums.length - 1 - i; j++) { System.out.println("j:" + j); if (arrayNums[j] > arrayNums[j + 1]) { System.out.println("entra"); int numGuardado = arrayNums[j + 1]; arrayNums[j + 1] = arrayNums[j]; arrayNums[j] = numGuardado; } print(arrayNums); } } return arrayNums; }
2. JUnit识别额外方法报错的问题
测试类同时继承了JUnit 3的junit.framework.TestCase和使用JUnit 5的@Test注解,导致测试框架同时识别两种规范的测试方法,出现冲突(TestCase类的默认方法会被当成测试方法)。
修复方法:二选一使用JUnit规范,推荐用JUnit 5的标准写法(去掉继承TestCase):
package exercise5; import org.junit.Assert; import org.junit.jupiter.api.Test; // 移除继承TestCase public class Ejercicio5Test { @Test public void resultadoCorrecto(){ int[] correct = {1,3,5,6,7,8}; int[] array = {6,5,8,3,7,1}; int[] result = Ejercicio5.sort(array); Assert.assertArrayEquals(result, correct); } @Test public void resultadoIncorrecto(){ int[] correct = {1,3,5,6}; int[] array = {3,5,6,1}; int[] result = Ejercicio5.sort(array); Assert.assertArrayEquals(result, correct); } }
内容的提问来源于stack exchange,提问作者h1294
相关产品推荐
相关产品推荐

