copyOf()
グァバのメソッドの『魔力』を感じてみたいguava-libraries
。
私がそれをチェックするために使用する小さなアプリがあります。
ドキュメントは次のとおりです。
JDK は
Collections.unmodifiableXXX
メソッドを提供しますが、私たちの意見では、これらは
- 扱いにくく冗長です。防御コピーを作成したいすべての場所で使用するのは不快です
- unsafe: 元のコレクションへの参照を誰も保持していない場合にのみ、返されるコレクションは真に不変になります。
そこで、モデルを構築しようとし"someone holds a reference to the original collection"
ます。したがって、コレクションのコピーを操作する場合、コピーの値を変更することについて心配する必要はありません。しかし、魔法は今のところうまくいきません (2 つの試行があります: 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);
}
}
}
出力:
ref: new
ref: new
これは、元のデータを変更したことを意味します。私たちが望まなかったもの。
質問
なぜコピーしないのですか?
とどう違うのunmodifiableXXX
?
同様の質問へのリンクがあります:
答えは次のように述べていcopyOf
ます:
- (ソースから)
copyOf(Collection)
インスタンスは一時的に作成しませんArrayList
(copyOf(Iterable)
そしてcopyOf(Iterator)
そうします)。