Java 对Bean 复杂对象深度复制

Bean 复杂对象深度复制

目录

Bean 复杂对象深度复制

1,实现clone();

未实现引用对象的clone

ShapeAni 代码:实现clone()

Animation 代码:

测试代码:

实现引用对象的clone

ShapeAnimation 代码:

Animation 代码:同上

测试代码:

2,串行化复制;

ShapeAnimationSerial代码: 实现 Serializable

AnimationSerial代码: 实现 Serializable

串行化代码:

测试代码:

总结:


学习了Bean单个对象的深复制,那如何对Bean复杂对象类型的数据进行深度复制,有几种方式呢?

 

1,实现clone();

未实现引用对象的clone

ShapeAni 代码:实现clone()

public class ShapeAni implements Cloneable {
    private String color;
    private String type;
    private Animation animation;

    public ShapeAni(String color, String type, Animation animation) {
        this.color = color;
        this.type = type;
        this.animation = animation;
    }

    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }

    public Animation getAnimation() {
        return animation;
    }

    public void setAnimation(Animation animation) {
        this.animation = animation;
    }

    @Override
    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

    @Override
    public String toString() {
        return "ShapeAni{" +
                "color='" + color + '\'' +
                ", type='" + type + '\'' +
                ", animation=" + animation +
                '}';
    }
}

Shape对象里面添加了Animation对象的引用

Animation 代码:

public class Animation {
    private String showType;
    private String showEffect;

    public Animation(String showType, String showEffect) {
        this.showType = showType;
        this.showEffect = showEffect;
    }

    public String getShowType() {
        return showType;
    }

    public void setShowType(String showType) {
        this.showType = showType;
    }

    public String getShowEffect() {
        return showEffect;
    }

    public void setShowEffect(String showEffect) {
        this.showEffect = showEffect;
    }

    @Override
    public String toString() {
        return "Animation{" +
                "showType='" + showType + '\'' +
                ", showEffect='" + showEffect + '\'' +
                '}';
    }
}

 

测试代码:

private static final String COLORS[] =
        { "红色", "粉红色", "绿色", "蓝色", "棕色", "橘色" };
private static final String SHAPES[] =
        { "圆形", "三角形", "长方形", "平行四边形", "扇形", "梯形" };

public static void main(String[] args) {
    Animation animation1 = new Animation("one","fade");
    Animation animation2 = new Animation("two","round");
    ShapeAni shapeAni1 = new ShapeAni("红色", "蓝色",animation1);
    ShapeAni shapeAni2 = (ShapeAni) shapeAni1.clone();
    shapeAni2.setColor(getRandomColor());
    shapeAni2.setType(getRandomShape());
    System.out.println(shapeAni1.toString());
    System.out.println(shapeAni2.toString());
    System.out.println("=========== set all inner object ===========");
    ShapeAni shapeAni3 = (ShapeAni) shapeAni1.clone();
    shapeAni3.setAnimation(animation2);
    System.out.println(shapeAni1.toString());
    System.out.println(shapeAni3.toString());
    System.out.println("===========  set part inner object ===========");
    ShapeAni shapeAni4 = (ShapeAni) shapeAni1.clone();
    shapeAni4.getAnimation().setShowEffect("roll");
    System.out.println(shapeAni1.toString());
    System.out.println(shapeAni4.toString());
}

private static String getRandomColor() {
    return COLORS[(int)(Math.random()*COLORS.length)];
}
private static String getRandomShape() {
    return SHAPES[(int)(Math.random()*COLORS.length)];
}

 

结果:

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='fade'}}

ShapeAni{color='绿色', type='梯形', animation=Animation{showType='one', showEffect='fade'}}

=========== set all inner object ===========

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='fade'}}

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='two', showEffect='round'}}

===========  set part inner object ===========

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='roll'}}

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='roll'}}

   从结果中,我们可以看出,如果单独操作ShapeAni里面的Animation的内容的时候,会影响到上一个内容。 在复杂对象的时候进行clone的时候,也要处理引用对象的复制

 

实现引用对象的clone

ShapeAnimation 代码:

public class ShapeAnimation implements Cloneable {
    private String color;
    private String type;
    private Animation animation;

    public ShapeAnimation(String color, String type, Animation animation) {
        this.color = color;
        this.type = type;
        this.animation = animation;
    }

    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }

    public Animation getAnimation() {
        return animation;
    }

    public void setAnimation(Animation animation) {
        this.animation = animation;
    }

    @Override
    public ShapeAnimation clone() {
        ShapeAnimation clone = null;
        try {
            clone = (ShapeAnimation) super.clone();
            clone.setAnimation(new Animation(clone.getAnimation().getShowType(),  clone.getAnimation().getShowEffect()));
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

    @Override
    public String toString() {
        return "ShapeAni{" +
                "color='" + color + '\'' +
                ", type='" + type + '\'' +
                ", animation=" + animation +
                '}';
    }
}

  Shape对象里面clone方法添加了Animation对象的复制,因为实例化,所以对象用了具体的类对象(public ShapeAnimation clone())。

Animation 代码:同上

   这边的代码,同上面一个例子的代码

测试代码:

private static final String COLORS[] =
        { "红色", "粉红色", "绿色", "蓝色", "棕色", "橘色" };
private static final String SHAPES[] =
        { "圆形", "三角形", "长方形", "平行四边形", "扇形", "梯形" };

public static void main(String[] args) {
    Animation animation1 = new Animation("one","fade");
    Animation animation2 = new Animation("two","round");
    // 先造一个原型
    ShapeAnimation shapeAni1 = new ShapeAnimation("红色", "蓝色",animation1);
    ShapeAnimation shapeAni2 = shapeAni1.clone();
    shapeAni2.setColor(getRandomColor());
    shapeAni2.setType(getRandomShape());
    System.out.println(shapeAni1.toString());
    System.out.println(shapeAni2.toString());
    System.out.println("=========== set all inner object ===========");
    ShapeAnimation shapeAni3 = shapeAni1.clone();
    shapeAni3.setAnimation(animation2);
    System.out.println(shapeAni1.toString());
    System.out.println(shapeAni3.toString());

    System.out.println("===========  set part inner object ===========");
    ShapeAnimation shapeAni4 = shapeAni1.clone();
    shapeAni4.getAnimation().setShowEffect("roll");
    System.out.println(shapeAni1.toString());
    System.out.println(shapeAni4.toString());
}

private static String getRandomColor() {
    return COLORS[(int)(Math.random()*COLORS.length)];
}
private static String getRandomShape() {
    return SHAPES[(int)(Math.random()*COLORS.length)];
}

 

结果:

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='fade'}}

ShapeAni{color='红色', type='圆形', animation=Animation{showType='one', showEffect='fade'}}

=========== set all inner object ===========

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='fade'}}

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='two', showEffect='round'}}

===========  set part inner object ===========

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='fade'}}

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='roll'}}

如果引用对象比较复杂的话,考虑对引用对象实现clone,这样就直接复制引用

@Override
public ShapeAnimation clone() {
    ShapeAnimation clone = null;
    try {
        clone = (ShapeAnimation) super.clone();
        Animation one = (Animation) clone.getAnimation ().clone();
        clone.setAnimationClone(one);
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    return clone;
}

 

2,串行化复制;

ShapeAnimationSerial代码: 实现 Serializable

public class ShapeAnimationSerial implements Serializable {
    private String color;
    private String type;
    private AnimationSerial animation;

    public ShapeAnimationSerial(String color, String type, AnimationSerial animation) {
        this.color = color;
        this.type = type;
        this.animation = animation;
    }

    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }

    public AnimationSerial getAnimation() {
        return animation;
    }

    public void setAnimation(AnimationSerial animation) {
        this.animation = animation;
    }

    @Override
    public String toString() {
        return "ShapeAni{" +
                "color='" + color + '\'' +
                ", type='" + type + '\'' +
                ", animation=" + animation.toString() +
                '}';
    }
}

因为使用串行化复制,所以引用对象也要实现Serializable

AnimationSerial代码: 实现 Serializable

public class AnimationSerial implements Serializable {
    private String showType;
    private String showEffect;

    public AnimationSerial(String showType, String showEffect) {
        this.showType = showType;
        this.showEffect = showEffect;
    }

    public String getShowType() {
        return showType;
    }

    public void setShowType(String showType) {
        this.showType = showType;
    }

    public String getShowEffect() {
        return showEffect;
    }

    public void setShowEffect(String showEffect) {
        this.showEffect = showEffect;
    }

    @Override
    public String toString() {
        return "Animation{" +
                "showType='" + showType + '\'' +
                ", showEffect='" + showEffect + '\'' +
                '}';
    }
}

 

串行化代码:

import java.io.*;
import java.util.List;
import java.util.Map;

public class CloneUtils {
    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T clone(T src){
        T cloneObj = null;
        try {
            ObjectInputStream ois = getInputStream(src);
            cloneObj = (T) ois.readObject();//返回生成的新对象
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cloneObj;
    }

    @SuppressWarnings("unchecked")
    public static <T> List<T> deepCopy(List<T> src)  {
        List<T> dest = null;
        try {
            ObjectInputStream ois = getInputStream(src);
            dest = (List<T>) ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dest;
    }

    @SuppressWarnings("unchecked")
    public static <K,V> Map<K,V> cloneMap(Map<K,V> src) throws IOException, ClassNotFoundException {
        Map<K, V> result = null;
        try {
            ObjectInputStream ois = getInputStream(src);
            result =  (Map<K, V>)ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private static ObjectInputStream getInputStream(Object src) throws IOException, ClassNotFoundException {
        //写入字节流
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream obs = new ObjectOutputStream(out);
        obs.writeObject(src);
        obs.close();
        //分配内存,写入原始对象,生成新对象
        ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
        return new ObjectInputStream(ios);
    }

    public static <T extends Serializable> T clones(T shape1) {
        T cloneObj = null;
        try {
            ObjectInputStream ois = getInputStream(shape1);
            cloneObj = (T) ois.readObject();//返回生成的新对象
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cloneObj;
    }
}

 

测试代码:

private static final String COLORS[] =
        { "红色", "粉红色", "绿色", "蓝色", "棕色", "橘色" };
private static final String SHAPES[] =
        { "圆形", "三角形", "长方形", "平行四边形", "扇形", "梯形" };

public static void main(String[] args) {
    System.out.println("=========== Serializable ===========");
    AnimationSerial animation1 = new AnimationSerial("one","fade");
    AnimationSerial animation2 = new AnimationSerial("two","round");
    ShapeAnimationSerial shapeAni1 = new ShapeAnimationSerial("红色", "蓝色",animation1);
    ShapeAnimationSerial shapeAni2 = CloneUtils.clone(shapeAni1);
    shapeAni2.setColor(getRandomColor());
    shapeAni2.setType(getRandomShape());
    System.out.println(shapeAni1.toString());
    System.out.println(shapeAni2.toString());

    System.out.println("=========== set all inner object ===========");
    ShapeAnimationSerial shapeAni3 = CloneUtils.clone(shapeAni1);
    shapeAni3.setAnimation(animation2);
    System.out.println(shapeAni1.toString());
    System.out.println(shapeAni3.toString());

    System.out.println("===========  set part inner object ===========");
    ShapeAnimationSerial shapeAni4 = CloneUtils.clone(shapeAni1);
    shapeAni4.getAnimation().setShowEffect("roll");
    System.out.println(shapeAni1.toString());
    System.out.println(shapeAni4.toString());
}

private static String getRandomColor() {
    return COLORS[(int)(Math.random()*COLORS.length)];
}
private static String getRandomShape() {
    return SHAPES[(int)(Math.random()*COLORS.length)];
}

 

结果:

=========== Serializable ===========

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='fade'}}

ShapeAni{color='粉红色', type='梯形', animation=Animation{showType='one', showEffect='fade'}}

=========== set all inner object ===========

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='fade'}}

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='two', showEffect='round'}}

===========  set part inner object ===========

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='fade'}}

ShapeAni{color='红色', type='蓝色', animation=Animation{showType='one', showEffect='roll'}}

总结:

     在使用bean复制对象复制的时候,如果使用clone()方法的时候,需要注意对引用对象的处理。如果有很多引用对象的话,考虑用串行话的方式进行复制。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天狼1222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值