访问指向ArrayList的指针?

时间:2013-09-26 07:05:03

标签: java design-patterns arraylist

我在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());
    }
}

3 个答案:

答案 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
}