I would like to feel the 'magic power' of the copyOf()
method of Guava guava-libraries
.
There is small app that I use to check it.
Here is the documentation:
The JDK provides
Collections.unmodifiableXXX
methods, but in our opinion, these can be
- unwieldy and verbose; unpleasant to use everywhere you want to make defensive copies
- unsafe: the returned collections are only truly immutable if nobody holds a reference to the original collection
So, I try to build a model where "someone holds a reference to the original collection"
. Thus, working with a copy of collection I should not be worried about changing value on copy. But magic does not work so far (there are two tries: 1. copyOf(collection)
, 2. copyOf(iterator)
):
import com.google.common.collect.ImmutableList;
import java.util.LinkedList;
import java.util.List;
class MyObject {
String name;
public MyObject(String name) {this.name = name;}
@Override
public String toString() {
return name;
}
}
public class ListUnsafe {
List<MyObject> list = new LinkedList<MyObject>();
{
list.add(new MyObject("a"));
list.add(new MyObject("b"));
list.add(new MyObject("c"));
}
public List<MyObject> getList() {
return ImmutableList.copyOf(list);
}
public List<MyObject> getCopyIterator() {
return ImmutableList.copyOf(list.iterator());
}
public static void main(String[] args) {
ListUnsafe obj = new ListUnsafe();
{
MyObject ref = obj.list.get(0);
List<MyObject> myList = obj.getList();
MyObject copyObj = myList.get(0);
copyObj.name = "new";
System.out.println("ref: " + ref);
}
obj = new ListUnsafe();
{
MyObject ref = obj.list.get(0);
List<MyObject> myList = obj.getCopyIterator();
MyObject copyObj = myList.iterator().next();
copyObj.name = "new";
System.out.println("ref: " + ref);
}
}
}
The output:
ref: new
ref: new
It means that we changed original data. What we did not want.
Why it does not do copy?
How it differs from unmodifiableXXX
?
There is link to similar question:
The answer says about copyOf
:
copyOf(Collection)
instance doesn't create temporary ArrayList
(copyOf(Iterable)
and copyOf(Iterator)
do so).In Java 8 and earlier versions, we can use collection class utility methods like unmodifiableXXX to create immutable collection objects. If we need to create an immutable list then use the Collections. unmodifiableList() method.
ImmutableList
does not magically make the elements immutable; it's the list that cannot be modified, not the elements it contains.ImmutableList.copyOf
makes a copy unless it is copying a list that is already an ImmutableList
. If you call ImmutableList.copyOf(list)
twice for the same immutable list, you will get two different copies.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