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());
    }
}
damat-perdigannat
  • 4,800
  • 1
  • 14
  • 27

3 Answers3

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?

Community
  • 1
  • 1
ashjtech
  • 91
  • 7
  • 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. – damat-perdigannat Sep 26 '13 at 07:55
  • 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. – damat-perdigannat Sep 27 '13 at 12:15
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.

William Gaul
  • 3,123
  • 2
  • 13
  • 21
  • Hi William, is there a way to semantically link "list" to "someOtherList"? That's exactly what I want to do. – damat-perdigannat Sep 26 '13 at 07:49
  • 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: http://stackoverflow.com/a/12429953/2749401 – William Gaul Sep 26 '13 at 08:03
  • 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. – damat-perdigannat Sep 26 '13 at 08:20
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
}
Thirumalai Parthasarathi
  • 4,251
  • 1
  • 22
  • 42
  • 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? – damat-perdigannat Sep 26 '13 at 10:53
  • @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? – Thirumalai Parthasarathi Sep 26 '13 at 10:57
  • If I can't refer to a reference then I can go for something like that. – damat-perdigannat Sep 26 '13 at 12:44
  • @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 a) { someotherlist = a; list = someotherlist;}` – Thirumalai Parthasarathi Sep 26 '13 at 15:29
  • 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. – damat-perdigannat Sep 27 '13 at 12:14
  • @bimboxX : Third party API..? i guess you mean "accessed from some other class". That is the reason why there are setters. mark the `someOtherList` as `private` so that using the setters is the only way to set an object to that reference. that is OOPS.. ;) :) – Thirumalai Parthasarathi Oct 01 '13 at 07:06
  • Hi Black Panther. Hmm.. No, I didn't mean "accessed from some other class". What I meant is like "the list belongs to another class" and I want to always have access to the said list from ListContainingObject. This is a case wherein ListContainingObject doesn't always have access to someOtherList. Got it? – damat-perdigannat Oct 01 '13 at 07:37
  • @bimboxX : im a little confused, the OP contains the `list`(the arraylist as an instance variable) inside the `ListContainingObject` class. and the `someOtherList` (the arraylist in the `main` method as local reference) is in the main method of the same class, so if you make the `someOtherList` as an instance variable of the class then you can use the setters without any problem. if i'm wrong, can you explain further for a deepr understanding of your problem? – Thirumalai Parthasarathi Oct 01 '13 at 07:56
  • @bimboxX : The design pattern of your code is very confusing dude.. what you are trying to achieve is make 2 distinct objects of 2 different classes to point to the same object in the heap, and if any one of the reference points to a new object, then the other reference should be pointing the newly pointing object. This is quite impossible.. if you could tell the purpose of this program, maybe a different but a feasible solution can be provided. – Thirumalai Parthasarathi Oct 01 '13 at 11:23
  • I don't have source code for Class Two (or in my case SomeOtherListContainingObjectWhichIsABlackBox), so I can't do it like that. However, I found a solution to my problem already which is to not point to someOtherList anymore. In my solution, I have to access solcowiab.getList() everytime instead of accessing listContainingObject.getList(). In that case I won't have to use the "list" variable anymore. Any pointers on my solution? (Pun not intended.) Thanks a lot by the way. – damat-perdigannat Oct 03 '13 at 07:18
  • always happy to help..:) – Thirumalai Parthasarathi Oct 03 '13 at 14:37