我写拷贝模式(prototype原型模式)

我写拷贝模式(prototype原型模式)

你拷贝或不拷贝,她一直在哪里,风力不走,雨里不去,你忍心留她一个人?哦可惜爱不是几滴眼泪几封情书哦— 这样的话或许有点残酷 等待着别人给幸福的人 往往过的都不怎么幸福!咔咔咔以上和拷贝(prototype原型模式)有半毛钱的关系吗?我这不是借物喻人,寓情于景吗,请原谅我的语文天赋点的有点歪……^_^~

开局一声吼,代码全靠编

哎客官不可以,洒家风华正茂,一时意气用事,当不得真,您容我重新组织一下语言。客官留步啊,您请~听~我~说~

听说白雪公主在逃跑,小红帽在担心大灰狼,啊我这嗓子一如既往的阔以,肿么办,辣么强,还要啥自行车。

坚决不跑题了哈,编起来go

话说天下大事,不对不对咳咳,话说有个People类俗称javaBean,长这吊样

public class People {

    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;
    }
}

长这吊样的多了去了,有啥用?

这不是要说到拷贝模式(prototype原始模型)吗,咱改一改给他来点料,实现一个标识接口Cloneable后变成这货了

public class People implements Cloneable{

    private String name;
    private int age;

    public People(String name, int age) {
        this.name = name;
        this.age = 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;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

如果不实现Cloneable,上面的clone方法是会报错的呀,当然了能报错就能解决,换成下方代码一次就好,我陪你天涯海角,oh不~

@Override
protected Object clone() throws CloneNotSupportedException {
     People people = new People(name,age);
     return (People)people;
}

PS一定要实现Cloneable不要问问什么,因为我不会告诉你这就是原型模式的核心哼(づ。◕‿‿◕。)づ

实现完了咱就测试一下代码的流畅度,测试代码如下:

public static void main(String[] args) {
        People people = new People("kevin",25);
        System.out.println("people:"+people.toString());
        try {
            Object clone = people.clone();
            if (clone instanceof People){
                People people1 = (People) clone;
                System.out.println("people1:"+people1.toString());
                System.out.println("people==people1: " + (people==people1));
                System.out.println("name: "+people.getName().equals(people1.getName()));
                System.out.println("age==age1: "+(people.getAge() == people1.getAge()));
            }
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

运行结果

people:name=kevin,age=25
people1:name=kevin,age=25
people==people1: false
name: true
age==age1: true

拷贝完以后数据是一样的说明是对的,但是巧的是name居然相等,age也居然相等,那不就是说引用的对象的地址是同一块地址呀,通俗的说,只是给这个people换了身行头因为(people==people1: false)看出来滴,内饰丝毫不改动呀,可能这样看的不清楚,咱给他加点work瞧一瞧

新People如下:

public class People implements Cloneable {

    private String name;
    private int age;
    private Work work;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
        this.work = new Work("it码农", 9527);
    }

    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 Work getWork() {
        return work;
    }

    public void setWork(Work work) {
        this.work = work;
    }

    @Override
    public String toString() {
        return "name=" + name + ",age=" + age;
    }

    class Work {
        private String workName;
        private int workNo;

        public Work(String workName, int workNo) {
            this.workName = workName;
            this.workNo = workNo;
        }

        public String getWorkName() {
            return workName;
        }

        public void setWorkName(String workName) {
            this.workName = workName;
        }

        public int getWorkNo() {
            return workNo;
        }

        public void setWorkNo(int workNo) {
            this.workNo = workNo;
        }
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

再来个测试代码看看

public static void main(String[] args) {
        People people = new People("kevin",25);
        System.out.println("people:"+people.toString());
        try {
            Object clone = people.clone();
            if (clone instanceof People){
                People people1 = (People) clone;
                System.out.println("people1:"+people1.toString());
                System.out.println("people==people1: " + (people==people1));
                System.out.println("name: "+people.getName().equals(people1.getName()));
                System.out.println("age==age1: "+(people.getAge() == people1.getAge()));
                System.out.println("work: "+(people.getWork() == people1.getWork()));
                People.Work work = people.getWork();
                People.Work work1 = people1.getWork();
                work.setWorkName("i am work...");
                System.out.println(work.getWorkName());
                System.out.println(work1.getWorkName());
            }
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

测试结果如下:

people:name=kevin,age=25
people1:name=kevin,age=25
people==people1: false
name: true
age==age1: true
work: true
i am work...
i am work...

注意(work: true)这次很直观的发现引入的work是相等的,也就是拷贝的people依旧持有被拷贝people的work,通过给work(people中的work)赋值(i am work…),work1(拷贝完后的对象people1中的work)也跟着改变了内容,也就是说我只是做了上层拷贝(浅拷贝)只是神似罢了,哇那我不就可以引出深入一点的问题(深拷贝)了吗,机智如我呀,不如去吃个鸡?咳咳跑题了哈,往下走走

深拷贝的People长如下这吊样,关键点是需要实现Serializable接口 ,People、Work必须要实现。因为我们要通过串行化来做深拷贝(deepClone方法),clone()方法咱做了浅拷贝,注Cloneable不能丢呀

public class People implements Cloneable,Serializable {

    private String name;
    private int age;
    private Work work;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
        this.work = new Work("it码农", 9527);
    }

    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 Work getWork() {
        return work;
    }

    public void setWork(Work work) {
        this.work = work;
    }

    @Override
    public String toString() {
        return "name=" + name + ",age=" + age;
    }

    class Work implements Serializable{
        private String workName;
        private int workNo;

        public Work(String workName, int workNo) {
            this.workName = workName;
            this.workNo = workNo;
        }

        public String getWorkName() {
            return workName;
        }

        public void setWorkName(String workName) {
            this.workName = workName;
        }

        public int getWorkNo() {
            return workNo;
        }

        public void setWorkNo(int workNo) {
            this.workNo = workNo;
        }
    }

    /**
     * 浅拷贝
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    /**
     * 深拷贝
     * @return
     */
    public Object deepClone() {
        ByteArrayOutputStream baos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(this);

            bais = new ByteArrayInputStream(baos.toByteArray());
            ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            close(baos);
            close(oos);
            close(bais);
            close(ois);
        }
        return null;
    }

    /**
     * 关闭流
     * @param closeable
     */
    private static void close(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

测试代码走一走:

public static void main(String[] args) {
         People people = new People("kevin", 25);
        System.out.println("people:" + people.toString());
        Object clone = people.deepClone();
        if (clone instanceof People) {
            People people1 = (People) clone;
            System.out.println("people1:" + people1.toString());
            System.out.println("people==people1: " + (people == people1));
            System.out.println("name: " + people.getName().equals(people1.getName()));
            System.out.println("age==age1: " + (people.getAge() == people1.getAge()));
            System.out.println("work: " + (people.getWork() == people1.getWork()));
            People.Work work = people.getWork();
            People.Work work1 = people1.getWork();
            work.setWorkName("i am work...");
            System.out.println(work.getWorkName());
            System.out.println(work1.getWorkName());
        }
    }

输出结果:

people:name=kevin,age=25
people1:name=kevin,age=25
people==people1: false
name: true
age==age1: true
work: false
i am work...
it码农

老铁们,(work: false)work不相等了,深拷贝成功了呀,修改work的workName不会再影响work1的workName啦,激动呀。

咦~这里的串行化不就是序列化和反序列化吗,老铁还不是信手拈来一段序列化代码

请看,序列化little toolKit:这可是我做redis缓存数据用的序列化呀,倾囊相授,不要迷恋我哦

public class SerializeUtil {

    /**
     * 单一对象序列化
     * @param object
     * @return
     */
    public static byte[] serialize(Object object) {
        if (object == null) {
            throw new IllegalArgumentException("object is null");
        }
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        byte[] bytes = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            bytes = baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            close(oos);
            close(baos);
            try {
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;
    }

    private static void close(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 单一对象反序列化
     * @param bytes
     * @return
     */
    public static Object unserialize(byte[] bytes) {
        if (bytes == null) {
            throw new IllegalArgumentException("bytes is null");
        }
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;
        try {
            bais = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            close(bais);
            close(ois);
        }
        return null;
    }

    /**
     * 列表数据的序列化
     * @param list
     * @return
     */
    public static byte[] serializeList(List<?> list) {
        if (list == null || list.size() == 0) {
            return null;
        }
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        byte[] bytes = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            for (Object o : list) {
                oos.writeObject(o);
            }
            bytes = baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            close(baos);
            close(oos);
        }
        return null;
    }

    /**
     * 列表数据的反序列化
     * @param bytes
     * @return
     */
    public static List<?> unserializeList(byte[] bytes) {
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;
        List<Object> list = new ArrayList<>();
        try {
            bais = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bais);
            while (bais.available() > 0){
                Object object = ois.readObject();
                if (object == null){
                    break;
                }
                list.add(object);
            }
            return list;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            close(bais);
            close(ois);
        }
        return null;
    }
}

一个明朗的天,心情随着音乐摇摆呀(◡ᴗ◡✿)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值