884
技術社區[雲棲]
Java Generic Deep Copy
原文:https://www.genericdeepcopy.com/
Java Generic Deep Copy
簡介:
Generic Deep Copy 是一個用於深度拷貝的java實用程序。這些被拷貝的對象不需要去實現Serializable,Cloneable或者任何其他的接口。基本上,這個程序可以深度拷貝任何java對象。在很多場合,使用它可以節省時間和精力。
使用場景:
無法進行係列化(non Serializable)的類並且它們來自第三方jars庫,因此對應的源碼無法改變;
無法進行係列化(non Serializable)的類並且有數百個類牽涉其中,因此手動更新它們是非常耗時的;
相對影子拷貝/淺複製(shallow copying),研究java反射和深度拷貝;
測試-創建一個拷貝,測試對象的改變,創建一個新的拷貝,再測試對象的改變。確保這些改變是一樣的,或者避免重新初始化一個主要實例。
這個程序還需要努力去改進,因此非常期待您的反饋。如果您下載並且試用了這個程序,請留下評論!這是該程序在各個場景下被測試使用的唯一途徑。
許可證:
由 Aaron Johnson 編寫的java程序Generic Deep Copy遵守modified Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License許可證。對於引用作品或者任何商業目的的商業授權,請參考聯係頁麵或者聯係銷售。
基本信息
這款軟件對於個人是可以免費使用的,並且不能用於商業(用於盈利)目的。
最近的代碼拷貝可以在以下網站找到:
https://www.genericdeepcopy.com.
允許:
- 你可以複製,修改並且傳播這個程序。
- 在個人使用或者非商業使用情況下,你可以使用這個程序。
限製:
- 這個提醒必須保持完整,並且一直和代碼一起發布,即使用於個人使用。
- 你必須按照作者或者許可證的方式來署名該作品。(但是,並不是任何情況下,他們讚成你或者你對作品的使用。)
- 你不能將這個作品用於商業目的。如果需要進行商業使用,請聯係作者。
- 如果你在這個作品之上進行更改,轉變,或者構建,你必須將最後的作品至於和本作品一樣的許可證之下。
- 你不可以對這個軟件進行逆向工程,反編譯,或者反匯編,也不能試圖使用其他的方式來活的源代碼。
詳細信息:
https://creativecommons.org/licenses/by-nc-sa/3.0/ (Summary)https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode (Detailed)
下載:
從這個網站下載該軟件,代表你已經同意這些許可證協議,包括你同意不會將該作品用於任何商業或者盈利的目的。
在下載之前,請閱讀許可證協議。
Generic Deep Copy 需要 Java 1.5及以上。
點擊下載:
DeepCopyUtil-1.4
實例和測試樣例
使用這個程序就像你在下麵的測試樣例中見到的一樣簡單。由於使用assertTrue() 和 assertFalse() 方法,jUnit會被用到。 調整了注釋使得代碼隻占用極少數行。
基本用法:
/** Basic usage of the utility. * @throws Exception */ public void testBasicUsage() throws Exception { DeepCopyUtil deepCopyUtil = new DeepCopyUtil(); // create deep copies of objects. // create an object CustomClass customObject = new CustomClass(); // create a copy of the object CustomClass copy = deepCopyUtil.deepCopy(customObject); assertFalse(customObject == copy); }
各種類類型
這個例子演示了簡單類的深度拷貝。/** Test that deep copy correctly copies basic object types. * @throws Exception */ public void testVariousTypes() throws Exception { DeepCopyUtil deepCopyUtil = new DeepCopyUtil(); // used to create deep copies of objects. Calendar cal = Calendar.getInstance(); int intArray[] = {1,2,3}; Integer integerArray[] = new Integer[]{1,2,3}; List<String> stringListFromArray = Arrays.asList(new String[]{"one", "two"}); List<String> normalList = new ArrayList<String>(); normalList.add("weeeeee"); Calendar calCopy = deepCopyUtil.deepCopy(cal); // create deep copies of objects. int intArrayCopy[] = deepCopyUtil.deepCopy(intArray); Integer integerArrayCopy[] = deepCopyUtil.deepCopy(integerArray); List<String> stringListFromArrayCopy = deepCopyUtil.deepCopy(stringListFromArray); List<String> normalListCopy = deepCopyUtil.deepCopy(normalList); assertFalse(cal == calCopy); // assure instances are different. assertFalse(intArray == intArrayCopy); assertFalse(integerArray == integerArrayCopy); assertFalse(stringListFromArray == stringListFromArrayCopy); assertFalse(normalList == normalListCopy); assertTrue(cal.equals(calCopy)); // assure values are the same. for (int i = 0; i < intArray.length; i++) { assertTrue(intArray[i] == intArrayCopy[i]); // int's use == } for (int i = 0; i < integerArray.length; i++) { assertFalse(integerArray[i] == integerArrayCopy[i]); // Integers use .equals assertTrue(integerArray[i].equals(integerArrayCopy[i])); } for (int i = 0; i < stringListFromArray.size(); i++) { // instances are different, values are equal. assertFalse(stringListFromArray.get(i) == stringListFromArrayCopy.get(i)); assertTrue(stringListFromArray.get(i).equals(stringListFromArrayCopy.get(i))); } for (int i = 0; i < normalList.size(); i++) { // instances are different, values are equal. assertFalse(normalList.get(i) == normalListCopy.get(i)); assertTrue(normalList.get(i).equals(normalListCopy.get(i))); } assertTrue(cal.getClass() == calCopy.getClass()); // assure class types are the same. assertTrue(intArray.getClass() == intArrayCopy.getClass()); assertTrue(integerArray.getClass() == integerArrayCopy.getClass()); assertTrue(stringListFromArray.getClass() == stringListFromArrayCopy.getClass()); assertTrue(normalList.getClass() == normalListCopy.getClass()); }
大型 LinkedList
深度拷貝超過包含100,000個對象的LinkedList/** Assure that a LinkedList of 100,000 elements can be deep copied. <br/> * Add -Xms512m and -Xmx1536m to the JVM args to see this work with 1,000,000. * @throws Exception */ public void testLinkedList() throws Exception { DeepCopyUtil deepCopyUtil = new DeepCopyUtil(); // used to create deep copies of objects. List<Integer> lst = new LinkedList<Integer>(); // Create a linked list of Integers. for (int i = 0; i < 100000; i++) { lst.add(i); } List<Integer> copyOfList = deepCopyUtil.deepCopy(lst); // create a deep copy assertTrue(copyOfList.size() == lst.size()); // test that the lists are the same size. assertFalse(copyOfList == lst); // test that the lists are not the same lists. // create some iterators instead of using list.get(), because we're using a LinkedList // and that would be slow. Iterator<Integer> origIt = lst.iterator(); Iterator<Integer> copyIt = copyOfList.iterator(); Integer origInt, copyInt; while (origIt.hasNext()) { // compare each of the items in both lists origInt = origIt.next(); copyInt = copyIt.next(); assertFalse(origInt == copyInt); // the lists should not be the same instance. assertTrue(origInt.equals(copyInt)); // the inner values should be the same. } }
循環引用
深度拷貝一個循環引用的類。這個類包含很多對自己的引用並且仍然能夠被正確拷貝。測試顯示,這些循環引用仍然能夠保持一樣的關係。(例如:內部實例仍然能夠正確的引用外部的類實例)package test.com.ajexperience.utils.deepcopyutil; import junit.framework.TestCase; import com.ajexperience.utils.DeepCopyUtil; public class DeepCopyTestSimpleCircle extends TestCase { public InnerClass outerToInner = new InnerClass(); // an instance of the inner class public DeepCopyTestSimpleCircle pointerToSelf; public class InnerClass { // an inner class with a link to the outer class DeepCopyTestSimpleCircle innerToOuter; } public DeepCopyTestSimpleCircle() { outerToInner.innerToOuter = this; // link the inner class to the outer class this.pointerToSelf = this; // self reference } public static void main(String args[]) throws Exception { DeepCopyUtil deepCopyUtil = new DeepCopyUtil(); // used to create deep copies of objects. DeepCopyTestSimpleCircle simpleCircle = new DeepCopyTestSimpleCircle(); // create an instance. DeepCopyTestSimpleCircle copy = deepCopyUtil.deepCopy(simpleCircle); // deep copy the object. assertFalse(simpleCircle == copy); // test that they are not equal. // test that the circular references are in tact. assertTrue(copy == copy.outerToInner.innerToOuter); assertTrue(copy == copy.pointerToSelf); } }
最後更新:2017-04-02 06:52:12