有時候因爲須要可能須要拷貝數組的中的數據,從而是咱們能更好的操做數據java
在這個時候咱們通常會想到數組的拷貝的方式,固然這種方式可使用,通常有addALL,和System.arraycopy。但必定要注意你的數組中放的是什麼數據,是對象仍是基本類型的數據。這一點很重要,接下來將經過測試代碼詳細介紹這些方法。數組
如下是java底層對addAll實現的方法。能夠看到其實是調用了System.arraycopy網絡
public boolean addAll(int index, Collection<? extends E> c) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: " + index + ", Size: " + size); Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }
public class TestArrayCopy { public static void main(String[] args) { Student[] s = {new Student(18,"Lucy"),new Student(20,"Lily")}; Student[] sBak = new Student[2]; //arraycopy(Object src, int srcStartIndex, Object dest, int destStartIndex, int length) //從指定源數組中複製一個數組,複製從指定的位置開始,到目標數組的指定位置結束。 //srcStartIndex:原數組中要開始複製的第一個元素的位置 //destStartIndex: 目標數組中要開始替換的第一個元素的位置 //length: 要複製的元素的個數 System.out.println("沒修改前"); for(int i=0; i<s.length; i++) { System.out.println(sBak[i] + "\t"); } System.arraycopy(s,0,sBak,0,s.length); System.out.println("------------------拷貝後----"); for(int i=0; i<s.length; i++) { System.out.println(sBak[i] + "\t"); } System.out.println(); System.out.println("------------------------------------"); System.out.println("修改後輸出原數組"); s[0].setAge(8888); s[0].setName("MicXP.com"); //這裏改的是sBak[0]引用的對像的值。 //sBak[0]=new Student(88,"MicXP"); //這裏是直接改sBak[0]引用地址。 for(int i=0; i<s.length; i++) { System.out.println(s[i] + "\t"); } System.out.println(); System.out.println("------------------------------------"); System.out.println("修改後輸出拷貝的數組"); for(int i=0; i<s.length; i++) { System.out.println(sBak[i] + "\t"); } } } class Student { private int age ; private String name ; Student(int age, String name) { this.age = age; this.name = name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return "姓名:"+ this.name +"\t"+"年齡:"+this.age; } }
從以上輸出結果能夠看出,當咱們修改了源數組中的對象,會影響目標數組的對象數據。因此這種拷貝方式是不靠譜的,並無真正將數據進行復制。ide
下面是測試基本數據類型的代碼。測試
public class TestArr { public static void main(String[] args) { // TODO Auto-generated method stub int a[] = {1,2,3,4}; int b[] = {2,3,4,5}; System.arraycopy(a,0,b,0,a.length); System.out.println("---------拷貝後-----" ); System.out.println("a---------->"); for(int i=0;i<a.length;i++){ System.out.print(a[i]+","); } System.out.println(); System.out.println("b---------->"); for(int i=0;i<b.length;i++){ System.out.print(b[i]+","); } a[3] = 45; System.out.println(); System.out.println("--------修改原數組"); System.out.println("a---------->"); for(int i=0;i<a.length;i++){ System.out.print(a[i]+","); } System.out.println(); System.out.println("b---------->"); for(int i=0;i<b.length;i++){ System.out.print(b[i]+","); } } }
 this
從以上數據結果能夠看出,當咱們拷貝數據後,修改源數組數據,不影響目標數組數據。spa
因此再數組拷貝的時候要注意這些問題,若是是對象則是拷貝引用。若是是基本數據類型,則拷貝的是真正的數據。code
        有什麼比較高效的真正拷貝數據的方法?clone?for循環再從新構造?若是你知道你經過評論告訴我,謝謝。對象
序列化和反序列化的定義:把Java對象轉換爲字節序列的過程稱爲對象的序列化。把字節序列恢復爲Java對象的過程稱爲對象的反序列化。進程
永久性保存對象,保存對象的字節序列到本地文件中
經過序列化在網絡中傳遞對象
經過序列化在進程間傳遞對象
(數組中的對象須要implements Serializable)
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; }