Java Collections.copy 方法
上次修改时间:2025 年 4 月 20 日
Collections.copy
方法是 Java 的 java.util.Collections
类中的一个实用方法。它将所有元素从一个列表复制到另一个列表。目标列表的长度必须至少与源列表一样长。
当您需要在列表之间传输元素时,同时保持目标列表的容量时,此方法非常有用。它执行浅拷贝,这意味着复制对象引用,而不是对象本身。
Collections.copy 方法概述
Collections.copy
方法的签名是:public static <T> void copy(List<? super T> dest, List<? extends T> src)
。如果目标列表太小,它会抛出 IndexOutOfBoundsException
,如果目标列表不可修改,则会抛出 UnsupportedOperationException
。
该方法保留元素的顺序,并覆盖目标列表中现有的元素。对于大型列表,它比手动复制更有效,因为它在内部使用原生数组复制。
基本复制操作
此示例演示了 Collections.copy
的基本用法。我们创建了两个 ArrayList 并将元素从源复制到目标。目标列表必须有足够的容量来容纳所有元素。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class BasicCopyExample { public static void main(String[] args) { // Source list List<String> source = new ArrayList<>(); source.add("Apple"); source.add("Banana"); source.add("Cherry"); // Destination list (must have same or larger size) List<String> destination = new ArrayList<>(); destination.add("X"); destination.add("Y"); destination.add("Z"); destination.add("W"); // Extra element System.out.println("Before copy:"); System.out.println("Source: " + source); System.out.println("Destination: " + destination); // Perform the copy Collections.copy(destination, source); System.out.println("\nAfter copy:"); System.out.println("Source: " + source); System.out.println("Destination: " + destination); } }
此代码显示了两个列表之间的基本复制操作。目标列表必须至少与源列表一样多的元素。复制后,额外的元素 "W" 仍然保留在目标列表中。
输出结果表明,元素在目标列表中被覆盖,同时保持顺序。源列表在操作后保持不变。
在不同列表类型之间复制
Collections.copy
适用于任何 List
实现。此示例从 ArrayList
复制到 LinkedList
。只要支持所需的操作,该方法对不同的列表实现具有灵活性。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; public class DifferentListTypes { public static void main(String[] args) { // ArrayList source List<Integer> arraySource = new ArrayList<>(); arraySource.add(10); arraySource.add(20); arraySource.add(30); // LinkedList destination List<Integer> linkedDest = new LinkedList<>(); linkedDest.add(0); linkedDest.add(0); linkedDest.add(0); System.out.println("Before copy:"); System.out.println("Source: " + arraySource); System.out.println("Destination: " + linkedDest); Collections.copy(linkedDest, arraySource); System.out.println("\nAfter copy:"); System.out.println("Source: " + arraySource); System.out.println("Destination: " + linkedDest); } }
此示例演示了不同 List
实现之间的互操作性。无论使用哪种特定的列表实现,复制操作都以相同的方式工作。
输出结果显示,元素已成功从 ArrayList
复制到 LinkedList
。目标列表的实现不会影响复制行为。
处理 IndexOutOfBoundsException
此示例显示了当目标列表对于源列表而言太小时会发生什么情况。在这种情况下,Collections.copy
抛出 IndexOutOfBoundsException
。在使用此方法时,适当的错误处理非常重要。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class CopyExceptionHandling { public static void main(String[] args) { List<String> source = new ArrayList<>(); source.add("Red"); source.add("Green"); source.add("Blue"); List<String> destination = new ArrayList<>(); destination.add("One"); destination.add("Two"); // Too small try { System.out.println("Attempting copy..."); Collections.copy(destination, source); System.out.println("Copy succeeded"); } catch (IndexOutOfBoundsException e) { System.out.println("Error: " + e.getMessage()); System.out.println("Destination list must be at least " + source.size() + " elements long"); } } }
此代码演示了当目标列表太小时发生的异常。错误消息清楚地表明了问题 - 目标列表的长度必须至少与源列表一样长。
输出结果显示了异常处理的实际效果。在调用 Collections.copy
之前,请务必确保目标列表具有足够的容量。
使用自定义对象复制
Collections.copy
适用于自定义对象,就像它适用于内置类型一样。此示例演示了复制自定义 Person
对象的列表。复制是浅拷贝 - 复制对象引用,而不是对象本身。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; class Person { String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return name + " (" + age + ")"; } } public class CustomObjectsCopy { public static void main(String[] args) { List<Person> source = new ArrayList<>(); source.add(new Person("Alice", 25)); source.add(new Person("Bob", 30)); List<Person> destination = new ArrayList<>(); destination.add(new Person("X", 0)); destination.add(new Person("Y", 0)); System.out.println("Before copy:"); System.out.println("Source: " + source); System.out.println("Destination: " + destination); Collections.copy(destination, source); System.out.println("\nAfter copy:"); System.out.println("Source: " + source); System.out.println("Destination: " + destination); source.getFirst().name = "Modified"; System.out.println("\nAfter modification:"); System.out.println("Source: " + source); System.out.println("Destination: " + destination); } }
此示例表明 Collections.copy
执行浅拷贝。目标列表中的 Person 对象与源列表中的对象相同。通过一个列表修改一个对象会影响两个列表。
输出结果表明,虽然列表是分开的,但它们包含对同一对象的引用。在使用可变对象时,这是一个重要的考虑因素。
复制到不可修改的列表
尝试复制到不可修改的列表会导致 UnsupportedOperationException
。此示例演示了此行为,并显示了如何正确处理它。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class UnmodifiableListCopy { public static void main(String[] args) { List<String> source = new ArrayList<>(); source.add("Java"); source.add("Python"); List<String> destination = Collections.unmodifiableList( new ArrayList<>(Collections.nCopies(2, ""))); try { System.out.println("Attempting to copy to unmodifiable list..."); Collections.copy(destination, source); } catch (UnsupportedOperationException e) { System.out.println("Error: " + e.getMessage()); System.out.println("Cannot copy to an unmodifiable list"); } } }
此代码尝试复制到不可修改的列表,这会抛出异常。 Collections.unmodifiableList
包装器阻止对列表进行所有修改,包括通过 copy
方法进行的修改。
来源
在本文中,我们深入探讨了 Collections.copy
方法。我们涵盖了基本用法、异常处理以及各种实际示例。理解此方法有助于在 Java 中使用列表操作时。
作者
列出所有Java教程。