• ArrayList(jdk 1.7.0_80)


      jdk1.7中有几个更新,List<Integer> l = new ArrayList();是允许的,更多的jdk1.7特性可参考:陈大大博客 http://blog.csdn.net/chenleixing/article/details/47802653。

      看源码,

    1 public class ArrayList<E> extends AbstractList<E>
    2         implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    3 {
    4  ...
    5 }

      ArrayList类继承AbstractList抽象类,实现List接口randomAccess、Cloneable、Serializable接口。这里列出接口源码是为之后分析List各个实现类之间的区别。也是提倡看源代码,看里面的代码结构和实现思路。

    1 public ArrayList(int initialCapacity) {
    2   super();
    3   if (initialCapacity < 0)
    4   throw new IllegalArgumentException("Illegal Capacity: "+
    5   initialCapacity);
    6   this.elementData = new Object[initialCapacity];
    7 }

    无参构造方法

    1 public ArrayList() {
    2   super();
    3   this.elementData = EMPTY_ELEMENTDATA;
    4 }

    1.ArrayList的构造方法,初始化有个DEFAULT_CAPACITY = 10;如果用无参构造方法,那么就是创建一个容量为10的ArrayList。装数据的对象是elementData,他是一个数组。数组的特点:易于查找,不便大批量插入数据和删除数据。

    2.add() **要注意看墨绿色 的注释,很容易就能看懂源码思路。

    1     public boolean add(E e) {
    2         ensureCapacityInternal(size + 1);  // Increments modCount!!
    3         elementData[size++] = e;
    4         return true;
    5     }

    E 类型是底层jdk中定义的一种类型,元素类型,

    第一步 ensureCapacityInternal(size+1); 作用是确保数组的大小足够大,能够放入这个e元素,这里做的就是size扩大1。先贴出源码,再细细分析他做了什么。

     1      private void ensureCapacityInternal(int minCapacity) {
     2         if (elementData == EMPTY_ELEMENTDATA) {//如果为空elementData,则取默认容量大小和传入参数之间的最大的
     3             minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
     4         }
     5 
     6         ensureExplicitCapacity(minCapacity);//创建数组对象,并让大小满足要求
     7     }
     8 
     9     private void ensureExplicitCapacity(int minCapacity) {//modecount记录操作结构的次数,即你每扩大一次数组大小就记录一次。
    10         modCount++;//modCount = modCount+1
    11 
    12         // overflow-conscious code
    13         if (minCapacity - elementData.length > 0)//如果要求的容积大于现在的大小,那么执行grow操作。
    14             grow(minCapacity);
    15     }
    16     
    17      private void grow(int minCapacity) {
    18         // overflow-conscious code 溢栈情况
    19         int oldCapacity = elementData.length;
    20         int newCapacity = oldCapacity + (oldCapacity >> 1);//扩大原来的一般,即1.5倍后
    21         if (newCapacity - minCapacity < 0)//如果扩大1.5倍任然小于需要的大小,那么赋值
    22             newCapacity = minCapacity;
    23         if (newCapacity - MAX_ARRAY_SIZE > 0)
    24             newCapacity = hugeCapacity(minCapacity);
    25         // minCapacity is usually close to size, so this is a win:
    26         elementData = Arrays.copyOf(elementData, newCapacity);//Arrays.copyOf()方法
    27     }

      这里Arrays.copyOf()方法将原来的elelmentData对象数据转移到另一个newCapacity大小的数组中,那么就实现了扩容的效果。最后将值放到size+1位置处。然后返回true,增加成功。

      ArrayList的add方法是相对简单的,在Map中的添加方法put方法会复杂些。

    3.get(int i) 

    1     public E get(int index) {
    2       return a[index];
    3     }

      比较容易理解,直接返回数组中位于index位置处的值。

      这里再讲一下迭代器Iterator,用法就是new一个Iterator对象,将ArrayList对象作为参数传入。然后不用for(int i =list;;){}其实迭代器做的功能就是循环输出list中的每个元素。

    ArrayList允许传入的是null,可以保存null。可以传入重复的值。保存的值是有序的,因为是序列,所以都是有序的。线程不安全,这里带过就可以了。

    **空重序安。按照这个顺序记是没错的。

      然后讲一下,为什么要在elementData前加transient字段。

      在序列化对象的时候,可能数组不是满,数组的大小是10,而只有三个位置是有值的,如果全部序列化会太浪费资源和时间,这里就用到了一个方法,将elementData中的数据取出,并序列化,不去序列化所有。具体实现是重写writeObject()方法实现的。

    不便将所有源码都贴出来,自己去看看吧。

      ArrayList与LinkedList之间的比较就放之后讲吧。

     
  • 相关阅读:
    基于Grafana的监控数据钻取功能应用实践
    将Windows下的InfluxDB、Grafana做成Windows服务
    基于InfluxDB实现分页查询功能
    Multipart/form-data POST文件上传详解
    RESTFUL接口
    正则表达式
    Spring Cloud简介
    Spring Boot初识(4)- Spring Boot整合JWT
    Spring Boot初识(3)- Spring Boot整合Swagger
    Spring Boot初识(2)- Spring Boot整合Mybaties
  • 原文地址:https://www.cnblogs.com/bamaofan/p/5788807.html
Copyright © 2020-2023  润新知