关于ArrayList的使用引发的一些思考

Posted 经理,天台风好大

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于ArrayList的使用引发的一些思考相关的知识,希望对你有一定的参考价值。

关于new ArrayList<>()的使用引发的一些思考,仅供参考


1、关于ArrayList源码理解

以前在写 new ArrayList<>() 时,后面的括号一般没有写过内容。某天突然发现这样一种写法:

List test = Arrays.asList("a","b");
System.out.println("test = " + test); //test = [a, b]

List a1 = new ArrayList<>(test);
System.out.println("a1 = " + a1); //a1 = [a, b]

于是查看了一下ArrayList相关的源码。

在new对象时截图如下,可以创建三种参数类型的对象: 默认、int、集合


分析源代码:

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity is negative
     * 构造具有指定初始容量的空列表。如果指定的初始容量为负数,则抛出:IllegalArgumentException
     */
    public ArrayList(int initialCapacity) 
        if (initialCapacity > 0) 
            this.elementData = new Object[initialCapacity];
         else if (initialCapacity == 0) 
            this.elementData = EMPTY_ELEMENTDATA;
         else 
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        
    

    /**
     * Constructs an empty list with an initial capacity of ten.
     * 构造一个初始容量为10的空列表。
     */
    public ArrayList() 
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    

    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     * 按照集合的迭代器返回元素的顺序构造一个包含指定集合元素的列表。
     * 如果指定的集合为空,则抛出:NullPointerException
     */
    public ArrayList(Collection<? extends E> c) 
        Object[] a = c.toArray();
        if ((size = a.length) != 0) 
            if (c.getClass() == ArrayList.class) 
                elementData = a;
             else 
                //这里是重点!copyOf:也就是将传入的参数复制一份
                elementData = Arrays.copyOf(a, size, Object[].class);
            
         else 
            // replace with empty array.替换为空数组
            elementData = EMPTY_ELEMENTDATA;
        
    

我们主要分析的是关于传进去一个集合的案例。

发现里面有一个 copyOf() 方法,也就是将传入的参数复制一份,到现有的集合中。

2、几种使用现象对比

可以通过几种现象的情况,对比理解回溯法。

现象一:直接将现有集合放到括号里面

//原有的List
List test = Arrays.asList("a","b");

// 使用方法1:
List a1 = new ArrayList<>(test);
System.out.println("a1 = " + a1);

//结果 a1 = [a, b]

现象二:通过新list的add()进行添加

//原有的List
List test = Arrays.asList("a","b");

// 使用方法2:
List a2 = new ArrayList();
a2.add(test);
System.out.println("a2 = " + a2);

//结果 a2 = [[a, b]]

现象3:在add()里面添加new ArrayList<>(test)

//原有的List
List test = Arrays.asList("a","b");

// 使用方法3:
List a3 = new ArrayList();
a3.add(new ArrayList<>(test));
System.out.println("a3 = " + a3);

//结果 a3 = [[a, b]]

发现现象2和现象3得到的结果是一样的

现象4:两种添加方法对比

//原有的list
List test = new ArrayList<>();
test.add("a");
test.add("b");

List res = new ArrayList<>();
//第一次添加,res值应该为ab
res.add(test);
System.out.println("result1 = " + res);
//第二次添加,res值按照自己的猜想应该是ab,abc
test.add("c");
res.add(test);
System.out.println("result1 = " + res +"发现两个元素竟然一样");

//结果:
//result1 = [[a, b]]
//result1 = [[a, b, c], [a, b, c]]发现两个元素竟然一样
//原有的list
List test = new ArrayList<>();
test.add("a");
test.add("b");
test.add("c")

List res2 = new ArrayList<>();
//第一次添加,res值应该为abc
res2.add(new ArrayList<>(test));
System.out.println("result2 = " + res2);
//第二次添加,res值按照自己的猜想应该是abc,abcd
test.add("d");
res2.add(new ArrayList<>(test));
System.out.println("result2 = " + res2+"发现两个元素不一样");

//结果:
//result2 = [[a, b, c]]
//result2 = [[a, b, c], [a, b, c, d]]发现两个元素不一样

3、总结

共同点:

  • 都是向res这个ArrayList中填加了一个名为test的链表

不同点:

  • res.add(new ArrayList(test)):开辟一个独立地址,地址中存放的内容为test链表,后续test的变化不会影响到res
  • res.add(test):将res尾部指向了test地址,后续test内容的变化会导致res的变化。

以上是关于关于ArrayList的使用引发的一些思考的主要内容,如果未能解决你的问题,请参考以下文章

由Java中List和ArrayList 引发的思考,什么是面向接口编程?

C#关于在返回值为Task方法中使用Thread.Sleep引发的思考

由Java中List和ArrayList 引发的思考,什么是面向接口编程?

由上一个血案引发的关于property和attribute关系的思考

一个Bug事件,引发我对 LiveData 与 协程 的思考

工作日记-物流门的业务流程异常引发的思考