我想将一个用户定义的类型(如下所示)添加到ArrayList.
import java.util.ArrayList;
class MyObj
{
int iX;
}
public class testForLoopjava
{
public static void main(String[] args)
{
MyObj ob1 = new MyObj();
ArrayList<MyObj> al = new ArrayList<MyObj>();
int a,b;
for(int i =0;i<5;i++)
{
ob1.iX = i + 5;
al.add(ob1);
}
for(int j=0;j<5;j++)
System.out.println("iX: "+al.get(j).iX);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试打印上面的代码时,iX始终打印9.ie iX由列表中的最后一个值更新.这是什么原因?我在做一些基本的错误.
输出:
iX: 9
iX: 9
iX: 9
iX: 9
iX: 9
Run Code Online (Sandbox Code Playgroud)
您每次都将相同的对象添加到列表中.您应该使用循环中创建的新实例.
例如-
ArrayList<MyObj> al = new ArrayList<MyObj>();
int a,b;
for(int i =0;i<5;i++)
{
MyObj ob1 = new MyObj();
ob1.iX = i + 5;
al.add(ob1);
}
Run Code Online (Sandbox Code Playgroud)
否则,你的列表将包含同一个实例的引用列表和修改一个实例会影响在该列表中的每个条目.
这种问题是尽可能使用不可变对象的强有力论据.如果可以的话,一个好的方法是iX在构造函数中实例化该字段,并使其final不允许它更改实例化后(检查Java final关键字).
public class MyObj {
private final int iX;
public MyObj(int i) {
iX = i; // iX is initialised here but can't be changed again
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法可以产生更安全的解决方案(如上所述),但需要注意的是您的对象可以在实例化后更改.这听起来像是一种限制性的做法,但你会惊讶地发现你的许多物品都可以用这种方式实现.