• 复制ArrayList的四种方式


    使用构造函数

    ArrayList有个构造函数,可以传入一个集合:

     1 public ArrayList(Collection<? extends E> c) {
     2     elementData = c.toArray();
     3     if ((size = elementData.length) != 0) {
     4         // c.toArray might (incorrectly) not return Object[] (see 6260652)
     5         if (elementData.getClass() != Object[].class)
     6             elementData = Arrays.copyOf(elementData, size, Object[].class);
     7     } else {
     8         // replace with empty array.
     9         this.elementData = EMPTY_ELEMENTDATA;
    10     }
    11 }

    上面的代码我们可以看出,底层实际上调用了Arrays.copyOf方法来对数组进行拷贝。这个拷贝调用了系统的native arraycopy方法,注意这里的拷贝是引用拷贝,而不是值的拷贝。这就意味着这如果拷贝之后对象的值发送了变化,源对象也会发生改变。

    举个例子:

        @Test
        public void withConstructor(){
            List<String> stringList=new ArrayList<>(Arrays.asList("a","b","c"));
            List<String> copyList = new ArrayList<>(stringList);
            copyList.set(0,"e");
            log.info("{}",stringList);
            log.info("{}",copyList);
    
            List<CustBook> objectList=new ArrayList<>(Arrays.asList(new CustBook("a"),new CustBook("b"),new CustBook("c")));
            List<CustBook> copyobjectList = new ArrayList<>(objectList);
            copyobjectList.get(0).setName("e");
            log.info("{}",objectList);
            log.info("{}",copyobjectList);
        }

    运行结果:

    22:58:39.001 [main] INFO com.flydean.CopyList - [a, b, c]
    22:58:39.008 [main] INFO com.flydean.CopyList - [e, b, c]
    22:58:39.009 [main] INFO com.flydean.CopyList - [CustBook(name=e), CustBook(name=b), CustBook(name=c)]
    22:58:39.009 [main] INFO com.flydean.CopyList - [CustBook(name=e), CustBook(name=b), CustBook(name=c)]

    我们看到对象的改变实际上改变了拷贝的源。而copyList.set(0,"e")实际上创建了一个新的String对象,并把它赋值到copyList的0位置。

    使用addAll方法

    List有一个addAll方法,我们可以使用这个方法来进行拷贝:

    @Test
    public void withAddAll(){
    
        List<CustBook> objectList=new ArrayList<>(Arrays.asList(new CustBook("a"),new CustBook("b"),new CustBook("c")));
        List<CustBook> copyobjectList = new ArrayList<>();
        copyobjectList.addAll(objectList);
        copyobjectList.get(0).setName("e");
        log.info("{}",objectList);
        log.info("{}",copyobjectList);
    }

    同样的拷贝的是对象的引用。

    使用Collections.copy

    同样的,使用Collections.copy也可以得到相同的效果,看下代码:

        @Test
        public void withCopy(){
            List<CustBook> objectList=new ArrayList<>(Arrays.asList(new CustBook("a"),new CustBook("b"),new CustBook("c")));
            List<CustBook> copyobjectList = new ArrayList<>(Arrays.asList(new CustBook("d"),new CustBook("e"),new CustBook("f")));
            Collections.copy(copyobjectList, objectList);
            copyobjectList.get(0).setName("e");
            log.info("{}",objectList);
            log.info("{}",copyobjectList);
        }

    使用stream

    我们也可以使用java 8引入的stream来实现:

    @Test
    public void withStream(){
    
        List<CustBook> objectList=new ArrayList<>(Arrays.asList(new CustBook("a"),new CustBook("b"),new CustBook("c")));
        List<CustBook> copyobjectList=objectList.stream().collect(Collectors.toList());
        copyobjectList.get(0).setName("e");
        log.info("{}",objectList);
        log.info("{}",copyobjectList);
    
    }
    四种方法都是引用拷贝,在使用的时候要小心。

    本文转载自:https://www.cnblogs.com/flydean/p/how-to-copy-list.html
  • 相关阅读:
    函数初识
    文件操作
    CentOS 7运维管理笔记(6)----Apache 基于 IP 的虚拟主机配置
    CentOS 7运维管理笔记(4)----安装ftp服务器
    CentOS 7运维管理笔记(3)----Linux路由器配置
    CentOS 7运维管理笔记(2)----修改命令提示符颜色
    CentOS 7运维管理笔记(1)----设置默认启动模式为GUI模式或命令行模式
    CentOS 7运维管理笔记(5)----源代码安装Apache 2.4,搭建LAMP服务器
    CentOS 7 下 安装Webmin 启动防火墙失败----Applying firewall rules:iptables-restore:line 2 failed
    CentOS 7 禁用IPV6以提高网速
  • 原文地址:https://www.cnblogs.com/seeyoumiter/p/14291723.html
Copyright © 2020-2023  润新知