7

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)インスタンスは一時的に作成しませんArrayListcopyOf(Iterable)そしてcopyOf(Iterator)そうします)。
4

2 に答える 2

20
  1. ImmutableList要素を魔法のように不変にするわけではありません。変更できないのはリストであり、含まれる要素ではありません。
  2. ImmutableList.copyOfは、すでにであるリストをコピーする場合を除き、コピーを作成しますImmutableListImmutableList.copyOf(list)同じ不変リストに対して 2 回呼び出すと、2 つの異なるコピーが取得されます。
于 2013-05-27T01:45:29.940 に答える