Javaのヒント----リストコピー:シャローコピーとディープコピー

オリジナル住所:  https://blog.csdn.net/demonliuhui/article/details/54572908

シャローコピーを一覧表示

ここで説明する絵を書きます

我々はすべて知っているように、リストは、本質的に配列され、アドレス形式の配列が格納されています。 
上の図の後にリストA浅いコピーは浅いコピーの結果として、Bを表示するには、AからBへの直接コピー、同じアドレスに同じコンテンツで同じアドレスのJavaを指すアレイ、すなわち、浅いコピーAとB点。変更は、アドレスの内容を変更することであるAも同じアドレスを指しているので、Bを指摘するので、Bと変化するので、その変化のBの結果はまた、A、Bを変更します

いくつかのシャローコピー

1、コピートラバーサルサイクル

一覧<人> destList = 新しいのArrayList <人> (srcList.size());  
(人物P:srcList){   
    destList.add(P)。  
}

 

2、クラスのコンストラクタのリストを使用して実装

List<Person> destList=new ArrayList<Person>(srcList); 

3、list.addAll()メソッドを使用して

一覧<人> destList = 新しいのArrayList <人> ();  
destList.addAll(srcList)。

 

4、System.arraycopyの()メソッドを使用して

人[] srcPersons = srcList.toArray(新しい人物[0 ])。  
人[] destPersons = 新しい人[srcPersons.length]。  
System.arraycopyの(srcPersons、 0、destPersons、0、srcPersons.length)。

 

テストと結果

がprintlist(destList); // プリント不変A B前 
srcList.get(0).setAge(100); // 変更B   
がprintlist(destList); // 変更BのA印字後
 // 印刷結果を 
123-- > 20である  
ABC > 21れている-は、  
ABC - > 22れる   
123 - > 100   
ABC > 21れる-   
ABC > 22である-が

一覧深いコピー

ここで説明する絵を書きます

示されるようにBとBのAは、新しいアドレスを作成しながら、ディープコピーは、コピーされ、次に、アドレスAの内容がアドレスBに転送されます。リスタListBの内容と一致して、しかし理由アドレスの異なる点で、お互いに影響を与えない変更。

ディープコピー方法

1.シリアル化メソッド

public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {  
    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();  
    ObjectOutputStream out = new ObjectOutputStream(byteOut);  
    out.writeObject(src);  
 
    ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());  
    ObjectInputStream in = new ObjectInputStream(byteIn);  
    @SuppressWarnings("unchecked")  
    List<T> dest = (List<T>) in.readObject();  
    return dest;  
}  
 
List<Person> destList=deepCopy(srcList);  //调用该方法

 

Java对对象和基本的数据类型的处理是不一样的。在Java中用对象的作为入口参数的传递则缺省为”引用传递”,也就是说仅仅传递了对象的一个”引用”,这个”引用”的概念同C语言中的指针引用是一样的。当函数体内部对输入变量改变时,实质上就是在对这个对象的直接操作。 除了在函数传值的时候是”引用传递”,在任何用”=”向对象变量赋值的时候都是”引用传递”。

2.clone方法

public class A implements Cloneable {   
    public String name[];   
 
    public A(){   
        name=new String[2];   
    }   
 
    public Object clone() {   
        A o = null;   
        try {   
            o = (A) super.clone();   
        } catch (CloneNotSupportedException e) {   
            e.printStackTrace();   
        }   
        return o;   
    }   
}  
for(int型 i = 0; iがN <; I + = ){ 
copy.add((A)src.get(I).clone())。
}

 

Javaはオブジェクトと処理の基本的なデータ型は同じではありません。デフォルトパラメータのエントリは、「参照渡し」されているとして使用するJavaオブジェクトを通過する際に、それは単に「基準」のオブジェクトを渡して、C言語のポインタを有する「参照」の概念は同じ参照します。入力変数を変更すると機能は、それは、物体の実質的に直接的な操作です。変数がされたときの関数値が、被験体に、「=」割り当てのいずれかを「参照渡し」されたときに通過することに加えて、「参照渡し」。

テストと結果

がprintlist(destList); // プリント不変A B前 
srcList.get(0).setAge(100); // 変更B   
がprintlist(destList); // B変更印刷
  
123 - > 20である  
ABC - - > 21である  
ABC - > 22は、   
123 - > 20であり、  
ABCは > 21である-   
ABC - > 22れます  

 

ソースデータの破壊が変更された後に浅いコピーの場合には、同じ変化を対象のデータ要素のセットに対応する同一の基準点も発生します。このように、ケースには需要の要件は、深いコピーでなければならないところ、そして上記の方法を使用している場合、リストTクラスオブジェクトが破壊され、簡単に外部に変更することはできませんことを確認してください。

おすすめ

転載: www.cnblogs.com/charles8866/p/10973128.html