【java基础】--ArrayList集合



前言

  集合主要是两组(单列集合,双列集合)
  Collection 接口有两个重要的子接口 List Set,他们的实现子类都是单列集合
  map 接口的实现子类是双列集合 存放的 k-v


一、Collection接口和常用方法

Collection接口常用方法,以实现子类 ArrayList来演示.CollectionMethod.java
1)add:添加单个元素
2) remove:删除指定元素
3)contains:查找元素是否存在
4) size:获取元素个数
5) isEmpty:判断是否为空
6) clear:清空
7) addAll:添加多个元素
8)containsAll:查找多个元素是否都存在
9)removeAll:删除多个元素
10) 说明:以ArrayList实现类来演示.

List接口的常用方法

ListMethod.java

List集合里添加了一些根据索引来操作集合元素的方法
1)void add(int index,Object ele):在index位置插入ele元素
2) boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
3)Object get(int index):获取指定index位置的元素
4)int indexOf(Object obj):返回obj在集合中首次出现的位置
5)int lastlndexOf(Object obj):返回obj在当前集合中末次出现的位置
6)Object remove(int index):移除指定index位置的元素,并返回此元素
7)Object set(int index,Object ele):设置指定index位置的元素为ele,相当于是替换.
8)List subList(int fromlndex,int tolndex):返回从fromlndex到tolndex位置的子集合 返回的是前闭后开的集合

ArrayList的注意事项

1)permits all elements,including null ,ArrayList可以加入null,并且多个
2)ArrayList是由数组来实现数据存储的
3)ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码在多线程情况下,不建议使用ArrayList

ArrayList底层结构和源码分析

1)ArrayList中维护了一个Object类型的数组elementData.[debug 看源码]transient //表示瞬间短暂的表示该属性不会被序列化 Object[] elementData;
2)当创建对象时,如果使用的是无参构造器,则初始elementData容量为0(jdk7是10)
3)当添加元素时:先判断是否需要扩容,如果需要扩容,则调用grow方法,否则直接添加元素到合适位置
4)如果使用的是无参构造器,如果第一次添加,需要扩容的话,则扩容elementData为10,如果需要再次扩容的话,则扩容elementData为1.5倍。
5)如果使用的是指定容量capacity的构造器,则初始elementData容量为capacity
6)如果使用的是指定容量capacity的构造器,如果需要扩容,则直接扩容elementData为1.5倍

在这里插入图片描述
确定是否要扩容

//确定是否要扩容然后再执行赋值操作 
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

确定minCapacity方法

    private static int calculateCapacity(Object[] elementData, int minCapacity) {
       if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
           return Math.max(DEFAULT_CAPACITY, minCapacity);	//第一次扩容为10
       }
       return minCapacity;
   }

   private void ensureCapacityInternal(int minCapacity) {
       ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
   }

判断集合的容量和修改次数

 private void ensureExplicitCapacity(int minCapacity) {
        modCount++;	//用来判断集合被修改的次数 防止多个线程同时修改集合 如果同时修改后抛异常

        // overflow-conscious code
        if (minCapacity - elementData.length > 0) //判断当前容量是否够
            grow(minCapacity);						//如果elementData的大小不够的话就调用grow方法去真的扩容
    }

集合源码扩容

//使用扩容机制来确定要扩容的多大
//第一次 nweCapacity = 10
//第二次及其以后按照1.5倍
//扩容使用的是Arrays.copyof() 会保留原先数据
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);		//确定按照1.5倍去扩容
        if (newCapacity - minCapacity < 0)						//判断扩容后的容量减去最小的容量 还小于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);	//将其数组内数据全部赋值为null
    }

如果集合使用了有参构造函数的话

//创建一个指定大小的elementData数组  
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);
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值