0

我在 Java 中有一个 ArrayList。现在,我想访问指向上述列表的指针。这样我就可以从指针中创建一个变量并使用它进行操作。关于如何做到这一点的任何建议?

我想要做的类似于使下面的“列表”始终指向“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);
    }
}

看似合适的解决方法是再次显式调用设置器,如下所示。

public class ListContainingObject {
    public void resetList(List toReset) {
        this.list = new ArrayList();
        toReset = this.list;
    }
}
listContainingObject.resetList(someOtherList);

但这会导致另一个问题,假设我没有 SomeOtherListContainingObjectWhichIsABlackBox 的源代码,我希望下面的 solcowiab.getList() 和 listContainingObject.getList() 始终相同。

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

3 回答 3

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 指的是相同的“列表”字段。

您必须再次将 setList 设置为新地址,因为 someOtherList 指的是不同的地址。因此,根据需要也应更新“列表”,并且必须在其他地方遵循。

假设您有一个方法可以修改此列表,您可以通过以下方式实现。

public void someMethod(){
 List someOtherList = getList();
 someOtherList =  new ArrayList();
 //some code
 setList(someOtherList);
}

对于类似的帖子检查:困惑,当传递对象引用时,java是使用按值调用还是按引用调用?

于 2013-09-26T07:23:44.603 回答
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);

然而,这是一个非常肮脏的 hack。但是,如果不以某种方式手动更改这两个变量以引用内存中的新结构,我就无法让一个变量自动更新另一个变量。

于 2013-09-26T07:24:32.850 回答
1

首先someotherlist是指向堆中的一个对象

someotherlist ----> 对象

那么你正在做两个引用来指向堆中的同一个对象

其他名单----

               |
             Object
               |

列表 - - - - - - -

现在,当您将引用分配给someotherlist堆中的新对象时

someotherlist ------> 新对象

引用的对象list不会改变

列表 -----------> 旧对象

您必须再次调用设置器以list指向新对象someotherlist

           Object (now eligible for garbage collection as referred by none)

其他物体 ------

                  |
             new Object
                  |

列表 - - -

注意: 您只能引用对象而不是对象引用..您可以做的是设置一种将对象设置为 someotherlist 的方法,并将相同的引用分配给列表也...像

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
}
于 2013-09-26T08:13:55.317 回答