为什么以下java代码导致无限循环?
import java.util.LinkedList;
import java.util.Random;
public class Main {
public static void main(String[] args) {
int n = 3;
Random rand = new Random();
LinkedList<Integer> fields = new LinkedList<Integer>();
for (int i = 0; i < n*n; i++) {
fields.add(i);
}
while (fields.size() > 0) {
// Choose Field
int f = rand.nextInt(fields.size());
fields.remove((Integer) f);
System.out.println(fields.size());
}
}
}
答案 0 :(得分:11)
使用remove
的方式,您可以按值删除对象,而不是按位置删除。
说明您的列表包含值[0, 1, 2, 3]
,并且前两次删除0
和1
。现在您有[2, 3]
,其大小为2,因此您现在永远不会删除3
!
要按位置而不是值移除,请说fields.remove(f)
。 (请注意,f
是一个整数,而(Integer)f
是列表容器中包含的类型的对象。)
(或者,对于不同的行为,您可以继续按值删除,但现在应该从范围[min, max]
中绘制随机数,您必须分别确定列表元素的极值。当然,加上很多,因为你会有很多&#34;错过&#34;你不会删除任何东西。)
答案 1 :(得分:5)
由于这一行:
fields.remove((Integer) f);
删除(Integer)
广告投放,它应该有用。
List中有两种删除方式:
remove(int)
和remove(E)
(出于兼容性原因,实际上是remove(Object)
)在您的情况下,E是Integer,并且由于自动装箱,您可以将int转换为Integer。通过这样做,您选择第二种类型,而您想要第一种类型。
答案 2 :(得分:2)
问题来自于您实际上是在调用remove(Object o)方法而不是remove(int index)方法!
当您致电fields.remove((Integer) f);
时,您不会删除索引f
处的对象,但会移除等于f
的整数,因为您的列表包含Integer
s < / p>
因此,不要将f
投射到Integer
,你应该没事。
另外,要从Integer
获取int
,请使用static Integer valueOf(int i)方法。
答案 3 :(得分:1)
import java.util.LinkedList;
import java.util.Random;
public class Main {
public static void main(String[] args) {
int n = 3;
Random rand = new Random();
LinkedList<Integer> fields = new LinkedList<Integer>();
for (int i = 0; i < n*n; i++) {
fields.add(i);
}
while (fields.size() > 0) {
// Choose Field
int f = rand.nextInt(fields.size());
fields.remove(f);
System.out.println(fields.size());
}
}
}
答案 4 :(得分:0)
单步执行调试器我可以看到您遇到的问题是您正在删除小于该大小的数字。然而,从那个数字开始,除非你在第一次永远不会删除时删除最大的数字。
您要做的是以随机顺序选择数字。最简单的方法是使用Collections.shuffle()
int n = 3;
List<Integer> list = new LinkedList<Integer>();
for (int i = 0; i < n * n; i++)
list.add(i);
Collections.shuffle(list);
System.out.println(list);
打印
[7, 4, 0, 8, 5, 1, 3, 6, 2]