0

I have an ArrayList in Java. Now, I want to access the pointer to the said list. This is so that I can make a variable out of the pointer and make operations using it. Any advise on how to do this?

What I want to do exactly is similar to making "list" below always point to the value of "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);
    }
}

The seemingly appropriate workaround would be to call the setters again explicitly like below.

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

But this would lead to another problem wherein I want solcowiab.getList() and listContainingObject.getList() below to always be the same, assuming that I don't have the source code for 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 Answers 3

1

You can't because the line someOtherList = new ArrayList(); is assigning a whole new "section of memory" to someOtherList, meaning it will point to a different place in memory than listContainingObject.getList().

Now it is true that the listContainingObject has only a reference to your created list, but this reference is not semantically linked to someOtherList. So if someOtherList changes, your object won't know about it.

If you want to clear the lists without destroying the link, use someOtherList.clear() instead.

EDIT: You may be able to get away with resetting the list another way:

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

This is, however, a pretty dirty hack. But without somehow manually changing both variables to reference the new structure in memory, I know of no way to get one to automatically update the other.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi William, is there a way to semantically link "list" to "someOtherList"? That's exactly what I want to do.
I have edited my post to show an idea I had, kind of backwards of what you're trying to do. But no, I don't think there is a way. This link should explain more why it isn't possible: stackoverflow.com/a/12429953/2749401
Thanks man. Really nice edit and link. I'm thinking maybe there can be a way such as extending the list to make it "observable" at some level or something. I'll try to +1 you once I get able.
1

Probably, you are trying to update the contents of the "list" field. Please find an solution here:

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

Thus, someOtherList is referring to the "list" field which is the same.

You have to again setList to the new address as once someOtherList is referring to different. So, as required "list" should be updated also and must be followed elsewhere.

Suppose you have a method, which modifies this list you can achieve this by below.

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

For similar post check: Confused, whether java uses call by value or call by reference when an object reference is passed?

2 Comments

Hi ashjtech, can you suggest a way to always make "list" point to where "someOtherList" is pointing? That is, when I change the object pointed to by "someOtherList", the "list" value will change also.
Thanks for the edit, man. It seems like calling the setter again (in someMethod) is the only way so far. I want to be even surer though that there's no other way. A problem can arise there too wherein someOtherList can be from a third party API and then we don't know when it changes the object it references. I'll try to give you +1 once I get able.
1

first the someotherlist is pointing to an object in heap

someotherlist ----> Object

then you are making two references to point to the same object in the heap

someotherlist ----

               |
             Object
               |

list -------------

now when you assign the reference someotherlist to a new object in the heap

someotherlist ------> new Object

the object refered by list will not be changed

list -----------> oldobject

you have to call the setters again to make list point to the new object refered by someotherlist

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

someotherobject ------

                  |
             new Object
                  |

list ------

Note: you can only refer objects not object references.. what you can do is set up a method for setting the object to someotherlist and assign the same reference to the list also... like

class Test {
  List<E> list;
  List<E> someOtherList;

  setterMethod(ArrayList<E> a) {
    someOtherList = a;
    list = someOtherList;
  }

Edit:

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
}

10 Comments

Hi dude, thanks for the diagram. I get it. Your answer is similar to William's answer. Could you suggest a way to create a variable that points to "someOtherList" instead of pointing to "new Object" in your illustration?
@bimboxX : you have to first understand how java's reference mechanism works. see an object can be referred by more than one reference. But you cannot have a reference for another reference. What you are asking is a way to refer to any object that is being referred by Someotherlist. is that what you are asking?
If I can't refer to a reference then I can go for something like that.
@bimboxX : that is not possible in java. you can only refer objects not object references.. what you can do is set up a method for setting the object to someotherlist and assign the same reference to the list also... like setterMethod(ArrayList<E> a) { someotherlist = a; list = someotherlist;}
Thanks for the edit and comment, man. It seems like calling the setter again is the only way so far. I want to be even surer though that there's no other way. A problem can arise there too wherein someOtherList can be from a third party API and then we don't know when it changes the object it references. I'll try to give you +1 once I get able.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.