Java 链接列表:无限循环
为什么下面的java代码会导致无限循环Java 链接列表:无限循环,java,list,Java,List,为什么下面的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
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());
}
}
}
import java.util.LinkedList;
导入java.util.Random;
公共班机{
公共静态void main(字符串[]args){
int n=3;
Random rand=新的Random();
LinkedList字段=新建LinkedList();
对于(int i=0;i0){
//选择字段
int f=rand.nextInt(fields.size());
字段。删除((整数)f);
System.out.println(fields.size());
}
}
}
由于这一行:
fields.remove((Integer) f);
删除(整数)
强制转换,它应该可以工作
列表中有两种类型的删除:
- 按位置移除:和
- 按内容删除:(实际上是
出于兼容性原因)remove(Object)
在您的例子中,E是整数,由于自动装箱,您可以将int转换为整数。通过这样做,您选择的是第二种类型,而您想要的是第一种类型。使用
remove
的方式,您可以通过值而不是位置来删除对象
假设您的列表由值[0,1,2,3]
组成,并且在前两次删除0
和1
。现在您有了大小为2的[2,3]
,因此您现在将永远不会删除3
要按位置而不是值删除,请说字段。删除(f)
。(请注意,f
是一个整数,而(integer)f
是列表容器中包含的类型的对象。)
(或者,对于不同的行为,您可以继续按值删除,但现在应该从范围[min,max]
中提取随机数,在该范围内,您必须分别确定列表元素的极值。当然,这可能需要更长的时间,因为您将有很多“未命中”不删除任何内容。)import java.util.LinkedList;
导入java.util.Random;
公共班机{
公共静态void main(字符串[]args){
int n=3;
Random rand=新的Random();
LinkedList字段=新建LinkedList();
对于(int i=0;i0){
//选择字段
int f=rand.nextInt(fields.size());
字段。删除(f);
System.out.println(fields.size());
}
}
}
逐步通过调试器,我可以看到您的问题是删除的数字小于调试器的大小。但是,从该数字开始,除非您第一次删除最大的数字,否则它将永远不会被删除
你要做的是以随机顺序选择数字。最简单的方法是使用Collections.shuffle()
您的问题来自于您实际调用的是方法而不是方法 调用
字段时,删除((整数)f)
您不删除索引f
处的对象,而是删除等于f
的整数,因为您的列表包含Integer
s
因此,不要将f
强制转换为Integer
,您应该会没事的
另外,要从
int
中获取整数,请使用该方法。在调试器中单步执行代码时,您会看到什么?真的吗?具有相同值的两个Integer
实例不满足从列表中删除的相等操作?@Kirk这不是关于两个不同的整数,这是关于重载方法的int vs Integer。@Sean,感谢您的编辑。我同意glowcoder的观点虽然可以说这是一个史诗般的重载失败方法。(为什么在C中是Remove
和RemoveAt
)
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());
}
}
}
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]