Java LinkedList clone() 方法
clone()
方法是 Java 中 Object
类的一个方法,用于创建并返回当前对象的一个副本。在 LinkedList
类中,这个方法被重写以实现链表的浅拷贝。
关键点:
- 返回的是一个新的
LinkedList
对象 - 新链表包含与原链表相同的元素
- 元素本身不会被复制(浅拷贝)
方法语法
public Object clone()
返回值:
- 返回此
LinkedList
的一个浅拷贝
异常:
- 不会抛出任何异常
如何使用 clone() 方法
基本用法示例
实例
import java.util.LinkedList;
public class LinkedListCloneExample {
public static void main(String[] args) {
// 创建原始链表
LinkedList<String> originalList = new LinkedList<>();
originalList.add("Apple");
originalList.add("Banana");
originalList.add("Cherry");
// 克隆链表
LinkedList<String> clonedList = (LinkedList<String>) originalList.clone();
// 打印两个链表
System.out.println("Original List: " + originalList);
System.out.println("Cloned List: " + clonedList);
}
}
public class LinkedListCloneExample {
public static void main(String[] args) {
// 创建原始链表
LinkedList<String> originalList = new LinkedList<>();
originalList.add("Apple");
originalList.add("Banana");
originalList.add("Cherry");
// 克隆链表
LinkedList<String> clonedList = (LinkedList<String>) originalList.clone();
// 打印两个链表
System.out.println("Original List: " + originalList);
System.out.println("Cloned List: " + clonedList);
}
}
输出结果:
Original List: [Apple, Banana, Cherry] Cloned List: [Apple, Banana, Cherry]
浅拷贝 vs 深拷贝
浅拷贝的特点
- 元素引用相同:克隆后的链表和原链表中的元素是同一个对象
- 修改元素影响双方:如果修改了链表中的对象,两个链表都会受到影响
实例
import java.util.LinkedList;
class Fruit {
String name;
Fruit(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class ShallowCopyExample {
public static void main(String[] args) {
LinkedList<Fruit> original = new LinkedList<>();
original.add(new Fruit("Apple"));
LinkedList<Fruit> cloned = (LinkedList<Fruit>) original.clone();
// 修改原始链表中的元素
original.get(0).name = "Orange";
System.out.println("Original: " + original);
System.out.println("Cloned: " + cloned);
}
}
class Fruit {
String name;
Fruit(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class ShallowCopyExample {
public static void main(String[] args) {
LinkedList<Fruit> original = new LinkedList<>();
original.add(new Fruit("Apple"));
LinkedList<Fruit> cloned = (LinkedList<Fruit>) original.clone();
// 修改原始链表中的元素
original.get(0).name = "Orange";
System.out.println("Original: " + original);
System.out.println("Cloned: " + cloned);
}
}
输出结果:
Original: [Orange] Cloned: [Orange]
如何实现深拷贝
如果需要完全独立的副本(包括元素),需要手动实现深拷贝:
实例
import java.util.LinkedList;
class Fruit implements Cloneable {
String name;
Fruit(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return name;
}
}
public class DeepCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
LinkedList<Fruit> original = new LinkedList<>();
original.add(new Fruit("Apple"));
LinkedList<Fruit> deepCloned = new LinkedList<>();
for (Fruit fruit : original) {
deepCloned.add((Fruit) fruit.clone());
}
// 修改原始链表中的元素
original.get(0).name = "Orange";
System.out.println("Original: " + original);
System.out.println("Deep Cloned: " + deepCloned);
}
}
class Fruit implements Cloneable {
String name;
Fruit(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return name;
}
}
public class DeepCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
LinkedList<Fruit> original = new LinkedList<>();
original.add(new Fruit("Apple"));
LinkedList<Fruit> deepCloned = new LinkedList<>();
for (Fruit fruit : original) {
deepCloned.add((Fruit) fruit.clone());
}
// 修改原始链表中的元素
original.get(0).name = "Orange";
System.out.println("Original: " + original);
System.out.println("Deep Cloned: " + deepCloned);
}
}
输出结果:
Original: [Orange] Deep Cloned: [Apple]
实际应用场景
- 保护原始数据:当需要操作链表但不想修改原始数据时
- 快速复制:需要快速创建一个内容相同的链表
- 多线程环境:在不同线程中使用相同数据的独立副本
注意事项
- 类型转换:clone() 返回 Object 类型,需要强制转换为 LinkedList
- 元素不变性:对于不可变对象(如 String),浅拷贝已经足够
- 性能考虑:克隆大型链表会有一定的性能开销
- 并发问题:克隆过程中如果链表被修改可能导致不一致
常见问题解答
Q1: clone() 方法和直接赋值有什么区别?
直接赋值(如 list2 = list1
)只是创建了一个新的引用指向同一个对象,而 clone()
创建了一个新的独立对象。
Q2: 为什么 clone() 方法返回 Object 而不是 LinkedList?
这是 Java 中 clone()
方法的标准设计,需要子类重写并返回更具体的类型。
Q3: 如何克隆自定义对象的 LinkedList?
确保自定义类实现了 Cloneable
接口并重写了 clone()
方法,然后按照深拷贝示例中的方法操作。
总结
LinkedList
的 clone()
方法提供了一种快速创建链表副本的方式,但需要注意它是浅拷贝。根据实际需求选择使用浅拷贝或实现深拷贝,特别是在处理包含可变对象的链表时。
点我分享笔记