Java跨类删除ArrayList指定对象的报错问题求助
我帮你梳理下删除功能里的几个关键问题,一个个来解决:
1. Scanner输入的换行残留问题
当你用s.nextInt()获取用户选择的4之后,输入流里还留着一个换行符,这时候紧接着调用s.nextLine()会直接读取到这个空字符串,导致你根本没拿到用户输入的菜单编码。
修复方法:在调用s.nextLine()之前,先调用一次s.nextLine()吃掉残留的换行,或者改用s.next()来读取菜单编码(因为next()会自动跳过空白字符)。
2. 字符串比较错误:用==代替equals()
Java里字符串比较内容必须用equals()方法,==比较的是对象的内存地址,哪怕内容一样,不同的字符串对象用==也会返回false,所以你的判断条件if(a == rm.get(i).getCode())永远不会成立,自然删不了元素。
修复方法:改成if(a.equals(rm.get(i).getCode())),如果要避免空指针,可以反过来写if(rm.get(i).getCode().equals(a))。
3. ArrayList删除元素的方式错误
你的rm是ArrayList<RegularMenu>,存储的是RegularMenu对象,而rm.remove(a)里的a是字符串,这会导致编译错误(因为remove()方法要么接受索引int,要么接受泛型类型的对象RegularMenu)。
修复方法:找到匹配的元素后,要么通过索引删除rm.remove(i),要么直接删除对象rm.remove(rm.get(i))。
4. 遍历删除元素时的索引错位问题
当你在for循环里删除元素后,ArrayList的大小会减小,后面的元素会往前移一位,这时候i继续递增,会跳过下一个元素。比如原来i=0,删了之后,原来的i=1的元素移到i=0,i变成1就会跳过它。
修复方法:可以用倒序遍历(从后往前删),或者用迭代器Iterator来遍历删除,这样更安全。
修正后的删除功能代码(input ==4的分支)
else if (input == 4){ System.out.println("Input menu code you want to delete"); // 处理nextInt()后的换行残留 s.nextLine(); // 吃掉之前的换行 String a = s.nextLine(); // 方法1:倒序遍历删除,避免索引错位 boolean isDeleted = false; for(int i = rm.size() - 1; i >= 0; i--){ RegularMenu menu = rm.get(i); if(menu.getCode().equals(a)){ rm.remove(i); isDeleted = true; System.out.println("Menu with code " + a + " deleted successfully!"); // 如果只需要删除第一个匹配项,可添加break; // break; } } if(!isDeleted){ System.out.println("No menu found with code " + a); } // 方法2:用迭代器删除(更推荐,适合复杂场景) /* Iterator<RegularMenu> iterator = rm.iterator(); boolean found = false; while(iterator.hasNext()){ RegularMenu menu = iterator.next(); if(menu.getCode().equals(a)){ iterator.remove(); found = true; System.out.println("Menu with code " + a + " deleted successfully!"); // 只删第一个就break,删所有匹配项就去掉break // break; } } if(!found){ System.out.println("No menu found with code " + a); } */ }
额外的小建议
- 把Scanner对象移到循环外面,不要每次循环都新建一个,这样更高效也避免潜在的输入问题:
Scanner s = new Scanner(System.in); int input; do{ // 循环内容 }while(input !=6); - 添加删除成功/失败的提示,让用户清晰知道操作结果。
内容的提问来源于stack exchange,提问作者Kevin Guswanto

