简体   繁体   中英

passing pointers to linked list using java. But when I modify the data in the memory/Array it's not updated in the Linked List. Why?

I am new in JAVA. I am trying to make couple of linked lists. All holding pointer/reference to some array element. Therefore, if I make any change in the array, it should reflect in the linked list. Right? In my program, the modification shows in the array, but the lists value are the same. (I deleted one element. it's not in the array anymore. but the linked list is still showing it)

I am passing references to linked list. if that works, why the modification is not working? Looks like the linked lists have their own copy of data. But, that is not how reference work.

Any explanation? Suggestion what else can be used to show the memory dependency?

"(I deleted one element. " you can't change the size of an array.

Based on what you are seeing most likely, if you deleted an element, you created a new array with one less element. This is why the object in your LinkedList doesn't appear to have changed.

first.add(WM.get(0)).

When you do this, it is the same as

Object referenceToObject = WM.get(0);
first.add(referenceToObject);

// removes the reference from WM.
WM.remove(0);
// this doesn't change referenceToObject or first
assert referenceToObject != null;
assert first.get(first.size() - 1) == referenceToObject;

But you can do this

// a reference to a reference.
AtomicReference<String> ref = new AtomicReference<>("Hello");

first.clear();
first.add(ref);

second.clear();
second.add(ref);

// all still there
assert first.get(0).get() == "Hello";
assert second.get(0).get() == "Hello";

// alter ref and all change
ref.set("World");
assert first.get(0).get() == "World";
assert second.get(0).get() == "World";

// or
ref.set(null);
assert first.get(0).get() == null;
assert second.get(0).get() == null;

There is no constructor or method in LinkedList to specify the backing array. It sounds like you have an array and a LinkedList and are adding an object to the array and then adding the object to the LinkedList instance. Removing the object from the array does not remove it from the LinkedList in this scenario. Based on your description, you should be adding your object to the LinkedList instance and using that as your source of truth.

Your linked list is not holding references to the "array element", but to the object referenced by the array.

// Create array
Person[] persons = new Person[2];
persons[0] = new Person("A");
persons[1] = new Person("B");

// Create linked list (of persons in reverse order)
LinkedList<Person> list = new LinkedList<>();
list.add(persons[1]);
list.add(persons[0]);

At this point, both persons (array) and list are referencing the two object (Person A and Person B). If you assign a new reference value to an array element, only the array is updated, not the list. However they both reference the same objects, so if you change the object, they both "see" it.

// Update array
persons[0] = new Person("C");

// Rename person B to B2
persons[1].setName("B2");

// Show content
System.out.println(persons[0] + ", " + persons[1]);
System.out.println(list);

Assuming Person has toString() implemented to return the name, this will be your output:

C, B2
[B2, A]

I've commented above but I think your response warrants an answer.

I made the array using ArrayListWM=new ArrayList<>. then I put some values manually using WM.add(string). created 2 lists first, second using LinkedList and put the pointers like this: first.add(WM.get(0)), second.add(WM.get(0)). then i deleted WM[0]. it shows. but first and second are unaffected.

As I mentioned in the comments Java is pass-by-value. It just so happens that when you pass objects you pass the value of the reference to that object.

When you do first.add(WM.get(0)) what happens is WM.get(0) gets evaluated and returns the reference. Then this reference is passed-by-value to first.add so now we have two references to your original object. Now when you 'delete' the value at WM[0] what you are actually doing is removing one reference to the original object. The other references stay intact.

How can I achieve call by reference? so that, everybody will be using/editing/updating the same object/array element?

For using and updating an object (mutating it's state by calling method on it) what you have is perfectly fine. If by update you mean replace all references of an object with references to another object then this goes against the point of Java's reference system. To quote an answer to a similar question; Don't don't this, even if you can.

Ultimately, what problem are you trying to solve? You've said you are new to Java, it might just be a case of learning the idiomatic Java approach to solve the problem rather than trying to use an approach you're familiar with.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM