Java集合面试题_java是什么

Java集合面试题_java是什么Java中的浅拷贝与深拷贝很多时候,我们期望去拷贝某个对象的副本。在Java中如果使用=赋值操作,其实际上会让两个引用变量指向同一个对象;而如果重新new一个新对象,再对各字段进行赋值操作时,将十分繁琐。为此在Java的Object类中,提供了一个clone方法,其可拷贝对象副本clone方法与Cloneable接口Cloneable接口的源码如下publicinterfaceCloneable{}注释第一段一个类实现了Cloneable接口,以向Object.c

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

Java 中的拷贝

由于java中只有值传递,u2 = u1,拿到的是u1的地址,u2和u1指向的是同一个内存区域,u1改变值,u2也会改变。

        UseCloneable u1 = new UseCloneable();
        UseCloneable u2 = u1;
        u1.a = 10;

在这里插入图片描述

那么我们怎么构造一个新的对象呢

        u2 = new UseCloneable();
        u2.a = u1.a;

但是如果有20个30个字段,这么写就比较臃肿。

clone 方法 与 Cloneable 接口

在这里插入图片描述


通俗理解

实现该接口并重写方法来实现拷贝。没实现该接口调用clone方法会报错。

Ojbect类中的clone方法

访问修饰符为protected ,只能由子类或者同包的类调用。

protected native Object clone() throws CloneNotSupportedException;

我们尝试调用clone方法,会提示CloneNotSupportedException

public static void main(String[] args) throws CloneNotSupportedException{ 
   
        UseCloneable u1 = new UseCloneable();
        u1.clone();
-------
Exception in thread "main" java.lang.CloneNotSupportedException: com.example.miccommon.collection.UseCloneable
	at java.lang.Object.clone(Native Method)
	at com.example.miccommon.collection.UseCloneable.main(UseCloneable.java:16)

实现接口实现拷贝过程

@Data
public class UseCloneable implements Cloneable { 
   

    private int a;
    private int b;
    private int c;
    private int d;
    private int e;
    private int f;
    private int g;

    public static void main(String[] args) throws CloneNotSupportedException { 
   

        UseCloneable vvvv = new UseCloneable();
        vvvv.setA(10);
        vvvv.setB(12);
        vvvv.setC(14);
        vvvv.setD(16);
        vvvv.setE(18);
        vvvv.setF(20);
        vvvv.setG(22);
        UseCloneable clone = (UseCloneable) vvvv.clone();
        System.out.println(clone);
    }

    @Override
    public String toString() { 
   
        return "UseCloneable{" +
                "a=" + a +
                ", b=" + b +
                ", c=" + c +
                ", d=" + d +
                ", e=" + e +
                ", f=" + f +
                ", g=" + g +
                '}';
    }
}
-------
UseCloneable{ 
   a=10, b=12, c=14, d=16, e=18, f=20, g=22}

可以看到是两个不同的对象

在这里插入图片描述

重写clone方法,来自定义克隆内容。

  @Override
    protected Object clone() throws CloneNotSupportedException { 
   
        UseCloneable clone = (UseCloneable) super.clone();
        clone.setA(999);
        return clone;
    }
-------
UseCloneable{ 
   a=999, b=12, c=14, d=16, e=18, f=20, g=22}

ArrayList 中相关的实现

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<Object> objects = new ArrayList<>();
        objects.add("123");
        Object o = objects.clone();
        System.out.println(o);

在这里插入图片描述

深拷贝

构造一个类Deep,通过clone拷贝。

@Data
public class UseCloneable implements Cloneable { 
   

    Deep deep;


    public static void main(String[] args) throws CloneNotSupportedException { 
   
        UseCloneable source = new UseCloneable();
        source.deep = new Deep();
        UseCloneable target = (UseCloneable) source.clone();
        System.out.println(target);
    }

}

class Deep { 
   

}

虽然source和target已经不是同一个对象,但是两个对象中的deep都是同一个指向。

在这里插入图片描述

我们稍作改造来看看有什么影响,在Deep类中加入属性A。

@Data
public class UseCloneable implements Cloneable { 
   

    Deep deep;

    public static void main(String[] args) throws CloneNotSupportedException { 
   
        UseCloneable source = new UseCloneable();
        source.deep = new Deep();
        source.deep.setA(10);
        UseCloneable target = (UseCloneable) source.clone();
        System.out.println(target);
        source.deep.setA(5);
        System.out.println(target);
    }

}

@Data
class Deep { 
   

    private int a ;

}
--------
UseCloneable(deep=Deep(a=10))
UseCloneable(deep=Deep(a=5))

对source的改动会影响到target中deep的字段,这样肯定是不合理的于是我们。

我们对代码进行改动

@Data
public class UseCloneable implements Cloneable { 
   

    Deep deep;

    public static void main(String[] args) throws CloneNotSupportedException { 
   
        UseCloneable source = new UseCloneable();
        source.deep = new Deep();
        source.deep.setA(10);
        UseCloneable target = (UseCloneable) source.clone();
        System.out.println(target);
        source.deep.setA(5);
        System.out.println(target);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException { 
   
        UseCloneable target = (UseCloneable) super.clone();
        Deep deep = target.getDeep();
        if (deep != null){ 
   
            Deep targetDeep = (Deep) target.getDeep().clone();
            target.setDeep(targetDeep);
        }
        return target;
    }
}

@Data
class Deep implements Cloneable { 
   

    private int a;

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

可以看到两个对象的deep的指向已经改变。

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/182246.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • wireshark网络安全分析工具之万文多图详解(持续更新)[通俗易懂]

    wireshark网络安全分析工具之万文多图详解(持续更新)[通俗易懂]1.基本介绍2.下载与安装3.详细教程3.1软件界面介绍3.1.1菜单栏3.1.2工具栏3.1.3数据包列表区3.1.4数据包详细区3.1.5数据包字节区3.2Wireshark过滤器3.2.1捕获过滤器3.2.2显示过滤器3.3过滤规则3.3.1语法讲解3.3.2过滤实例4.实战案例

    2022年6月21日
    23
  • PDF文档免费转成Word文档,不限页数。

    PDF文档免费转成Word文档,不限页数。链接:https://download.csdn.net/download/auspicious_air/10942678断网状态下输入序列号Name:SolidConverterPDFv9E-mail:user@ru.ruOrganization:anyUnlockCode:KTGK

    2022年4月28日
    57
  • spring 中StoredProcedure的使用方法

    spring 中StoredProcedure的使用方法StoredProcedure是一个抽象类,必须写一个子类来继承它,这个类是用来简化JDBCTemplate运行存储过程操作的。首先我们写一个实现类:packagecom.huaye.framework.dao;importjava.sql.Types;importjava.util.HashMap;importjava.util.Map;…

    2022年7月26日
    6
  • 大数据——数据流式处理「建议收藏」

    大数据——数据流式处理「建议收藏」一、概念大数据中包含两种处理方式:流处理和批处理。流处理:即流式处理。流式处理假设数据的潜在价值是数据的新鲜度,需要尽快处理得到结果。在这种方式下,数据以流的方式到达。在数据连续到达的过程中,由于流携带了大量数据,只有小部分的流数据被保存在有限的内存中。流处理方式用于在线应用,通常工作在秒或毫秒级别。 批处理:批处理方式中,数据首先被存储,然后再分析。MapReduce是非常重要的…

    2022年5月23日
    203
  • javaweb项目集成editor.md编辑器—markdown编辑器

    javaweb项目集成editor.md编辑器—markdown编辑器最近写一个博客系统,需要集成编辑器,所以我就打算集成一个markdown编辑器用来编辑文章。在网上搜,好像editor.md这个国产开源的markdown编辑器比较好。不过想吐槽是网上的教程真的。。。哈哈哈,开始我们的教程:1.首先在editor.md官网(http://pandao.github.io/editor.md/)下载这一个编辑器。这是下载好后的文件目录2.将目录下的css目

    2022年9月17日
    0
  • Attributable_文件属性里没有自定义

    Attributable_文件属性里没有自定义在做项目的时候,用没人写的代码和看Android源码时,经常看attr.xml的使用,每次都不知道是什么意思,今天网上查了些资料,终于明白了,这里做一个笔记,方便以后使用这里与一个关于AttributeSet的应用场景:一个自定义控件的有些属性内容是随着外部条件而动态改变的,forexample:一个自定义的ListView控件,需要在底部添加一个View,而这个View在不同的模块使用

    2022年10月26日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号