zoukankan      html  css  js  c++  java
  • java ArrayList

    基于jdk1.8

    先来一张集合的图片:


    集合的关系都在图上面,可以先熟悉一下。

    接下来的内容都是基于这张图吧。

    当然我们学习要有重点,接下来就看下哪几点?

    1、是否允许空

    2、是否允许重复数据

    3、是否有序,有序的意思是读取数据的顺序和存放数据的顺序是否一致

    4、是否线程安全

    ArrayList

    好的ArrayList是我们常见的集合类,它是一个以数组形式存储数据的集合,接下来看下重要的元素:

    元    素 作    用
    private transient Object[] elementData; ArrayList是基于数组的一个实现,elementData就是底层的数组
    private int size; ArrayList里面元素的个数,这里要注意一下,size是按照调用add、remove方法的次数进行自增或者自减的,所以add了一个null进入ArrayList,size也会加1 

    四个关注点在ArrayList上的答案

    以后每篇文章在讲解代码前,都会先对于一个集合关注的四个点以表格形式做一个解答:

    关  注  点 结      论

    ArrayList是否允许空

    允许
    ArrayList是否允许重复数据 允许
    ArrayList是否有序 有序
    ArrayList是否线程安全 非线程安全

    添加元素

    有这么一段代码:

    public static void main(String[] args)
    {
        List<String> list = new ArrayList<String>();
        list.add("000");
        list.add("111");
    }

    看下底层会做什么,进入add方法的源码来看一下:

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

    第二步是扩容,先不管,第三步是增加一个元素。

    扩容

    构造ArrayList的时候,默认的底层数组大小是空

    public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    那么有一个问题来了,底层数组的大小不够了怎么办?答案就是扩容,这也就是为什么一直说ArrayList的底层是基于动态数组实现的原因,动态数组的意思就是指底层的数组大小并不是固定的,而是根据添加的元素大小进行一个判断,不够的话就动态扩容,扩容的代码就在ensureCapacity里面:
    private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
    minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
    }
    如果为空那么初始化为大小为10的数组。
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;//数据结构发生改变,和fail-fast机制有关,在使用迭代器过程中,只能通过迭代器的方法(比如迭代器中add,remove等),修改List的数据结构, 如果使用List的方法(比如List中的add,remove等),修改List的数据结构,会抛出ConcurrentModificationException
    //所以循环删除的时候用迭代器。
        // overflow-conscious code 当前数组容量不足时进行扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    如果现在大小不够则会扩容。找到最小的,然后调用到的是Arrays的copyOf方法,将元素组里面的内容复制到新的数组里面去。

    删除元素

    接着我们看一下删除的操作。ArrayList支持两种删除方式:

    1、按照下标删除

    2、按照元素删除,这会删除ArrayList中与指定要删除的元素匹配的第一个元素

    其实做的事情就是两件:

    1、把指定元素后面位置的所有元素,利用System.arraycopy方法整体向前移动一个位置

    2、最后一个位置的元素指定为null,这样让gc可以去回收它

    技巧:要将list中去重,把对象放入Set中,然后重新赋值就好了。

    
    
    
  • 相关阅读:
    互评Beta版本——可以低头,但没必要——取件帮
    作业要求 20181127-5 Beta发布用户使用报告
    从程序员到CTO的Java技术路线图
    feodora git command autocomplete
    java case
    哑铃 图解
    links
    编辑被标记为“只读”的Word文档
    css装饰文本框input
    css中background-image背景图片路径设置
  • 原文地址:https://www.cnblogs.com/faker2014/p/7191747.html
Copyright © 2011-2022 走看看