ArrayList的clone方法-浅拷贝与深拷贝

2020-04-29  本文已影响0人  木木点

首先ArrayList的本质是维护了一个Object的数组,所以克隆也是通过数组的复制实现的,属于浅拷贝。

clone方法的源码:

    public Object clone() {
        try {
            ArrayList<?> v = (ArrayList<?>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size); //这里,就是通过数组的复制实现的
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }

那么浅拷贝和深拷贝的定义是什么呢?对于ArrayList实例就是指:两个实例指示内存中的地址是不一样的,但是实例中的元素指向同一个元素。深层拷贝是指,不仅仅实例指示的内存地址不一样,而且实例中的各个元素所指地址也是不一样的。

我看的例子:

浅拷贝:

        ArrayList<Student> list = new ArrayList<Student>();
        //添加两个元素
        Student stJack = new Student("Jack", 13);
        Student stTom = new Student("Tom", 15);
        list.add(stJack);
        list.add(stTom);
        //克隆
        ArrayList<Student> listCopy = (ArrayList<Student>) list.clone();
        //移除并修改元素的内容,。
        listCopy.remove(1);
        listCopy.get(0).setAge(66);
        System.out.println(list);
        System.out.println(listCopy);

输出结果:

[Student [name=Jack, age=66], Student [name=Tom, age=15]]
[Student [name=Jack, age=66]]

解读:

remove之前的:

JIxmHU.png

remove之后的:

JIxM4J.png

深拷贝:

import java.util.ArrayList;

public class TestClone {
    public static void main(String[] args) {
        ArrayList<Student> list=new ArrayList<Student>();
        //添加两个元素
        Student stJack=new Student("Jack", 13);
        Student stTom=new Student("Tom", 15);
        list.add(stJack);
        list.add(stTom);
        
        //深拷贝
        ArrayList<Student> listCopy=new ArrayList<Student>();
        for (Student student : list) {
            listCopy.add(student.clone());
        }
        //对listCopy的元素修改不影响list的元素
        listCopy.get(0).setAge(20);
        System.out.println(list);
        System.out.println(listCopy);

    }
}

class Student{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
    @Override
    protected Student clone(){
        Student stuent = new Student(this.name,this.age);
        return stuent;
    }

}

输出结果:

[Student [name=Jack, age=13], Student [name=Tom, age=15]]
[Student [name=Jack, age=20], Student [name=Tom, age=15]]
上一篇下一篇

猜你喜欢

热点阅读