我正在寻求改进我的Java编码。
是否有人可以提供链接或解释是否存在初始化ArrayLists的操作规范并避免以下问题:
- 我在一个类中有6个ArrayList,有些是其他类的子集。因为有些是其他的子集我理解它们通过“addAll()”和“add()”方法共享相同的引用。
结果,通过尝试改变子集中的元素,我也在改变原始集合,因为它们共享相同的引用。我的代码非常混乱,一些“get”调用导致我的两个ArrayLists被重置。
我研究了这个论坛和谷歌,我似乎无法找到我想要的相关信息。我只找到了ArrayLists的简单示例。我注意到在这个论坛上有一些与ArrayList参考相关的问题所以我认为这个问题的答案将来会对其他人有所帮助。
答案 0 :(得分:3)
是否有人可以提供链接或解释是否存在初始化ArrayLists的操作规范并避免以下问题:
在初始化ArrayLists时,没有这样的练习代码或最佳实践或其他任何内容。
问题基本上是你需要理解在使用对现有对象的引用和创建新对象之间的差异。然后你需要选择合适的...... 取决于你想要做什么。
(在这个主题上询问“最佳做法”就像是否应该使用+
或-
运营商那样询问“最佳做法”...)
我建议你回到Java教科书/教程/讲座笔记,然后阅读:
而不是谷歌搜索“最佳实践”。new
运算符的作用。 确保真正了解它们。当你理解它们时,你将能够理解在你的程序中使用哪些来做你想做的事。
答案 1 :(得分:1)
addAll添加对ArrayList中对象的引用,而不是对象的副本。如果你想复制,你必须遍历第一个ArrayList,并且对于每个Object,调用将创建该对象副本的“clone”函数,并将其添加到新的ArrayList中。
示例:
public static void main(String[] args) {
ArrayList<Foo> A = new ArrayList<Foo>();
A.add(new Foo("foo1", 1));
A.add(new Foo("foo2", 2));
ArrayList<Foo> B = new ArrayList<Foo>();
System.out.println("Before: ");
System.out.println("A:");
for(Foo foo:A){
System.out.println(foo);
try {
B.add((Foo)foo.clone());
} catch (CloneNotSupportedException ex) {
//Never Gonna Happen
}
}
System.out.println("B:");
for(Foo foo:B){
System.out.println(foo);
}
A.remove(0);
System.out.println("After:");
System.out.println("A:");
for(Foo foo:A){
System.out.println(foo);
}
System.out.println("B:");
for(Foo foo:B){
System.out.println(foo);
}
}
public static class Foo{
private String Name;
private int Id;
public Foo(String Name, int Id) {
this.Name = Name;
this.Id = Id;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return new Foo(Name,Id);
}
@Override
public String toString() {
return "Name: "+Name+", Id: "+Id;
}
}
打印出来:
Before:
A:
Name: foo1, Id: 1
Name: foo2, Id: 2
B:
Name: foo1, Id: 1
Name: foo2, Id: 2
After:
A:
Name: foo2, Id: 2
B:
Name: foo1, Id: 1
Name: foo2, Id: 2
如果处理您创建的类的ArrayLists,请确保它们都覆盖了“clone”函数。对于包含您也创建的类的类,请使用您为父类“clone”中的内部类创建的“clone”函数。等等。