I've looked around and cannot figure this one out: I have a object that implemens an observer pattern and a List implementation that allows listeners to be added on the list whenever a change event is triggered on any object in the list to avoid manual add/remove listeners to each object int the list.
The problem I have is when creating a new instance of the same List implementation and adding objects from existing lists the object changes are not getting triggered from beans added to the new list. My thought was that when adding an object to a Collection it just adds a pointer to the existing object which given this case the change notifications would be getting triggered on objects in the new list but this is not happening. Can anyone help me figure out what the problem might be? I have seen similar questions but none that can help me solve this problem.
The use case, is a stock scanner where one list has all the stocks in the market I'm watching and the scanner list only has the stocks that pass the criteria but the scanner is not getting updates like price, volume etc that get triggered using the observation pattern. - Duncan
Your understanding was correct; collections hold references to objects. For example, this:
final StringBuilder stringBuilder = new StringBuilder();
final List<StringBuilder> stringBuilderList = new ArrayList<StringBuilder>();
stringBuilderList.add(stringBuilder);
stringBuilderList.add(stringBuilder);
stringBuilder.append("yes");
System.out.println(stringBuilderList);
will print this:
[yes, yes]
because there was only a single StringBuilder instance, so the appended "yes" is in every element of the list.
But note that the collections hold those references by value, not by reference. For example, this:
StringBuilder stringBuilder = new StringBuilder("yes");
final List<StringBuilder> stringBuilderList = new ArrayList<StringBuilder>();
stringBuilderList.add(stringBuilder);
stringBuilder = new StringBuilder("no");
// now stringBuilder refers to a different object than before
stringBuilderList.add(stringBuilder);
System.out.println(stringBuilderList);
will print this:
[yes, no]
because the two elements of the list refer to different objects, even though both objects were identified by the same variable.
For more help in figuring out what's going wrong with your code, I think you'll have to post a minimal program that demonstrates the issue.
By value, always!
When it comes to objects, the value passed is the value of the reference, but not the reference it self.
See most of these links
Languages where pass by reference is supported ( Java doesn't support this ) can perform the following:
Foo foo = new Foo();//create a new object
foo.name("Old foo"); // label it
modify( foo ); // try to modify it
// In a language that supports byRef will print "New foo".
// In Java will print "Old foo" always
println( foo );
...
void modify( Foo foo ) {
foo = new Foo(); // reference assigned a new different object
foo.name("New foo");
}
So, languages that support pass by reference, will put the new object created inside the method to the reference passed to them ( they receive the reference after all ). Languages like C++ and VB can do this..
Languages that doesn't support pass by reference ( like Java ) won't assign the new object to the original reference, Java will assigned it to the copy of the reference ( the one created in the argument passing --> void modify( Foo foo ) { ) But the original one, the one created before the method will remain intact and thus still with Old foo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With