java:List的深拷贝

 相关方法调用:
void org.apache.commons.collections.CollectionUtils.addAll(Collection collection, Object[] elements)
Integer[] java.util.List.toArray(Integer[] a)
void java.util.Collections.copy(List<? super Integer> dest, List<? extends Integer> src)

1. CollectionUtils.addAll与Collections.copy结合实现深拷贝。

import org.apache.commons.collections.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CopyTest {

    public static void main(String[] args) {

        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(i);
        }

        //list深度拷贝
        List<Integer> newList = new ArrayList<>();
        CollectionUtils.addAll(newList, new Object[list.size()]);
        Collections.copy(newList, list);
        newList.set(0, 10);
        
        System.out.println("原list值:" + list);
        System.out.println("新list值:" + newList);
    }
}

测试结果:

原list值:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
新list值:[10, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2. List.toArray与CollectionUtils.addAll结合实现深拷贝

    /**
     * 深拷贝:
     * 现将list使用list.toArray转成数组,再使用CollectionUtils.addAll复制到新的list中
     */
    @Test
    public void test2(){
        List<Integer> oldList = new ArrayList<Integer>();
        for (int i = 0; i < 10; i++) {
            oldList.add(i);
        }
        
        Integer[] intArray = new Integer[oldList.size()];
        oldList.toArray(intArray);
        //输出intArray进行查看
        String str = "";
        for(Integer inte : intArray){
            str = str + inte + ",";
        }
        System.out.println("---intArray : "+str);
        
        List<Integer> newList = new ArrayList<Integer>();
        CollectionUtils.addAll(newList, intArray);
        System.out.println("---1---newList.size()=" + newList.size());
        System.out.println("---1---新list值:" + newList);
        
        newList.set(0, 10);
        System.out.println("原list值:" + oldList);
        System.out.println("新list值:" + newList);
    }

执行结果:

---intArray : 0,1,2,3,4,5,6,7,8,9,
---1---newList.size()=10
---1---新list值:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
原list值:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
新list值:[10, 1, 2, 3, 4, 5, 6, 7, 8, 9]

3、在使用Collections.copy(dest, src)时,目标dest的长度必须大于等于src的长度;
举例如下:

List src1 = new ArrayList( 3 )
src1.add( " a " );
src2.add( " b " );
src3.add( " c " );

如果使用下面方法copy链表:
/** **************************** */
List des1 = new ArrayList( 3 );
Collections.copy(des1,src1);
/** **************************** */
将会出错,抛出数组越界异常。
当时我怎么想都想不明白为什么,明明已经设置了长度为3,为什么还会出错!
后来打印出des1.size()才知道des1的长度为0;3表示的是这个List的容纳能力为3,并不是说des1中就有了3个元素。查看api才知 道,它的capacity(容纳能力大小)可以指定(最好指定)。而初始化时size的大小永远默认为0,只有在进行add和remove等相关操作 时,size的大小才变化。然而进行copy()时候,首先做的是将desc1的size和src1的size大小进行比较,只有当desc1的 size 大于或者等于src1的size时才进行拷贝,否则抛出IndexOutOfBoundsException异常。
java.util.Collections.copy()方法注意点 - 我的JAVA快乐生活 - CSDN博客 https://blog.csdn.net/liulin_good/article/details/6109090
4、Collections.copy实现的是覆盖替换,而不是追加新增;

@Test
    public void test3(){
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < 10; i++) {
            list.add(i);
        }

        //list深度拷贝
        List<Integer> newList = new ArrayList<Integer>();
//        CollectionUtils.addAll(newList, new Object[list.size()]);
        for (int i = 0; i < 15; i++) {
            newList.add(i+100);
        }
        System.out.println("---1---newList.size()=" + newList.size());
        System.out.println("---1---newList值:" + newList);
        
        Collections.copy(newList, list);
        System.out.println("---2---newList.size()=" + newList.size());
        System.out.println("---2---newList值:" + newList);
        newList.set(0, 10);
        
        System.out.println("原list值:" + list);
        System.out.println("新list值:" + newList);
    }

 执行结果:

---1---newList.size()=15
---1---newList值:[100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114]
---2---newList.size()=15
---2---newList值:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 110, 111, 112, 113, 114]
原list值:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
新list值:[10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 110, 111, 112, 113, 114]

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页