我在Java中有一个ArrayList。现在,我想访问指向所述列表的指针。这样我就可以从指针中创建一个变量并使用它来进行操作。有关如何做到这一点的任何建议吗?
我想要做的就是使下面的“list”始终指向“someOtherList”的值。
import java.util.ArrayList;
import java.util.List;
public class ListContainingObject {
private List list;
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public static void main(String args[]){
ListContainingObject listContainingObject= new ListContainingObject();
System.out.println(listContainingObject.getList());
List someOtherList = new ArrayList();
listContainingObject.setList(someOtherList);
System.out.println(listContainingObject.getList());
System.out.println(someOtherList);
someOtherList.add("1");
System.out.println(listContainingObject.getList());
System.out.println(someOtherList);
//I want the two below to have the same value
someOtherList = new ArrayList();
System.out.println(listContainingObject.getList());
System.out.println(someOtherList);
}
}
看似合适的解决方法是再次明确地再次调用setter。
public class ListContainingObject {
public void resetList(List toReset) {
this.list = new ArrayList();
toReset = this.list;
}
}
listContainingObject.resetList(someOtherList);
但这会导致另一个问题,其中我希望下面的solcowiab.getList()和listContainingObject.getList()始终相同,假设我没有SomeOtherListContainingObjectWhichIsABlackBox的源代码。
import java.util.ArrayList;
import java.util.List;
public class ListContainingObject {
private List list;
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public static void main(String args[]) {
ListContainingObject listContainingObject = new ListContainingObject();
SomeOtherListContainingObjectWhichIsABlackBox solcowiab = new SomeOtherListContainingObjectWhichIsABlackBox();
List aNewList = new ArrayList();
aNewList.add("1");
solcowiab.setList(aNewList);
listContainingObject.setList(solcowiab.getList());
System.out.println(listContainingObject.getList());
System.out.println(solcowiab.getList());
//The two below will have the same value but
//at some point "list" did not point to "someOtherList"
solcowiab.aMethodThatSupposedlyWontCallSetList();
listContainingObject.setList(solcowiab.getList());
System.out.println(listContainingObject.getList());
System.out.println(solcowiab.getList());
}
}
class SomeOtherListContainingObjectWhichIsABlackBox {
private List someOtherList;
public List getList() {
return someOtherList;
}
public void setList(List list) {
this.someOtherList = list;
}
public void aMethodThatSupposedlyWontCallSetList() {
//this one won't be observed by ListContainingObject
setList(new ArrayList());
getList().add("2");
//do some other stuff
//only this assignment will be controlled by ListContainingObject's main method
setList(new ArrayList());
}
}
答案 0 :(得分:1)
您可能正在尝试更新“列表”字段的内容。 请在此处找到解决方案:
import java.util.ArrayList;
import java.util.List;
public class ListContainingObject {
private List list;
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public static void main(String args[]){
ListContainingObject listContainingObject= new ListContainingObject();
System.out.println(listContainingObject.getList());
List someOtherList = new ArrayList();
listContainingObject.setList(someOtherList);
System.out.println(listContainingObject.getList());
System.out.println(someOtherList);
someOtherList = listContainingObject.getList();
someOtherList.add("1");
System.out.println(listContainingObject.getList());
System.out.println(someOtherList);
//I want the two below to have the same value
//someOtherList = new ArrayList();
someOtherList.clear();
System.out.println(listContainingObject.getList());
System.out.println(someOtherList);
}
}
因此,someOtherList指的是相同的“list”字段。
你必须再次将setList设置为新地址,因为someOtherList指的是不同的。因此,根据需要,“list”也应该更新,并且必须在其他地方进行。
假设您有一个修改此列表的方法,您可以通过以下方式实现此目的。
public void someMethod(){
List someOtherList = getList();
someOtherList = new ArrayList();
//some code
setList(someOtherList);
}
对于类似的帖子检查:Confused, whether java uses call by value or call by reference when an object reference is passed?
答案 1 :(得分:1)
你不能因为行someOtherList = new ArrayList();
正在分配一个全新的内存部分"到someOtherList
,意味着它将指向内存中与listContainingObject.getList()
不同的位置。
现在listContainingObject
只有对您创建的列表的引用,但此引用在语义上并未链接到someOtherList
。因此,如果someOtherList
发生变化,您的对象就不会知道它。
如果要在不破坏链接的情况下清除列表,请改用someOtherList.clear()
。
编辑:您可以通过另一种方式重置列表:
public class ListContainingObject {
public void resetList(List toReset) {
this.list = new ArrayList();
toReset = this.list;
}
}
listContainingObject.resetList(someOtherList);
然而,这是一个相当肮脏的黑客。但是,如果不以某种方式手动更改两个变量以引用内存中的新结构,我知道无法让一个变量自动更新另一个。
答案 2 :(得分:1)
首先someotherlist
指向堆中的对象
someotherlist ---->对象
然后你要引用两个引用指向堆中的同一个对象
someotherlist ----
| Object |
列出-------------
现在将引用someotherlist
分配给堆中的新对象
someotherlist ------>新对象
list
提到的对象不会被更改
list ----------->的OLDobject
您必须再次致电设置者,使list
指向someotherlist
Object (now eligible for garbage collection as referred by none)
someotherobject ------
| new Object |
列出------
注意:强> 你只能引用对象而不是对象引用。你可以做的是设置一个方法来将对象设置为其他列表,并为列表分配相同的引用...比如
class Test {
List<E> list;
List<E> someOtherList;
setterMethod(ArrayList<E> a) {
someOtherList = a;
list = someOtherList;
}
修改强>
class One {
List<E> list;
public void setList(List<E> newList) {
this.list = newList;
}
//getters and setters and other methods
}
class Two {
One one;
List<E> someOtherList;
public void setSomeOtherList(List<E> newList) {
this.someOtherList = newList;
this.one.setList(newList);
}
//getters and setters and other methods
}