Java中列表复制的2种方法比较

Java中列表复制2种办法:

  • Collections.copy(a,b)
  • 在原来列表上直接创建一个新列表如 b = new ArrayList(a)

两者有啥区别?

1、复制方法Collections.copy(a, b):

  • Collections.copy 方法用于将一个列表(b--源列表)中的所有元素复制到另一个列表(a--目标列表)中。
  • 目标列表(a)的长度必须至少与源列表(b)的长度相同,否则将产生 IndexOutOfBoundsException 异常。
  • 它将用源列表中的元素覆盖目标列表中的元素。它不会创建一个新列表,而是修改现有列表。
  • 源列表和目标列表的类型必须兼容。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CopyExample {
    public static void main(String[] args) {
        List<Integer> sourceList = new ArrayList<>();
        sourceList.add(1);
        sourceList.add(2);
        sourceList.add(3);

        List<Integer> destinationList = new ArrayList<>(sourceList.size());
        destinationList.add(0);
        destinationList.add(0);
        destinationList.add(0);

        Collections.copy(destinationList, sourceList);

        System.out.println("Source List: " + sourceList);
        System.out.println(
"Destination List: " + destinationList);
    }
}

2、基于原来旧的创建新列表 
List b = new ArrayList(a);

  • 创建了一个新的 ArrayList (b),它是源 list (a) 中元素的浅层副本。它创建了一个全新的列表对象。
  • 对其中一个列表的修改不会影响另一个列表。它实质上是创建了一个 ArrayList 的新实例,其元素与源列表相同。

import java.util.ArrayList;
import java.util.List;

public class NewArrayListExample {
    public static void main(String[] args) {
        List<Integer> sourceList = new ArrayList<>();
        sourceList.add(1);
        sourceList.add(2);
        sourceList.add(3);

        List<Integer> newList = new ArrayList<>(sourceList);

        System.out.println("Source List: " + sourceList);
        System.out.println(
"New List: " + newList);
    }
}

两者比较
1、内存分配:

  • Collections.copy(a, b) 对现有列表进行操作。它不会为目标列表 (b) 分配新的内存。相反,它会将源列表 (a) 中的元素复制到目标列表 (b) 的现有存储空间中。
  • b = new ArrayList(a) 创建一个新的 ArrayList 对象。该对象有自己独立的内存分配。构造函数将源列表 (a) 中的元素复制到目标列表 (b) 新分配的内存中。

2.容量:
  • Collections.copy(a,b)假设目标列表(b)的容量已经足够容纳源列表(a)中的所有元素。如果没有,就会产生 ArrayIndexOutOfBoundsException 异常。
  • b = new ArrayList(a) 可以指定目标列表 (b) 的初始容量。您可以传递源列表 (a) 的大小,以确保预先分配了足够的容量。

浅层复制与深层复制:

  • 两种方法默认都执行浅复制。这意味着元素本身会被复制,但元素中的对象引用会在两个列表中共享。修改一个列表中的元素也会修改另一个列表中的相应元素。
  • 如果需要深度复制,即嵌套对象也被独立复制,则需要使用另一种方法,如 Apache Commons Lang 库中的 copy.deepcopy(a)。

选择正确的方法:

  • 如果需要对现有列表执行浅层复制,并且确信目标列表有足够的容量,Collections.copy(a, b) 是一种简洁高效的选择。
  • 如果需要指定目标列表的初始容量或执行深度复制,则首选 b = new ArrayList(a) 或 copy.deepcopy(a) 方法。