• Java集合框架(一)-ArrayList


    大佬理解->Java集合之ArrayList

    1、ArrayList的特点

    存放的元素有序
    元素不唯一(可以重复)
    随机访问
    插入删除元素
    非线程安全

    2、底层实现

    底层初始化,使用一个Object类型的空对象数组,初始长度为0;
    

    源码

    //Object类型对象数组引用
    transient Object[] elementData;
    //默认空的Object数组
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    //实例化时,将Object类型对象数组引用 指向 默认空的Object数组
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    
    

    首次添加元素,自动进行扩容,默认扩充容量是10(数组的长度,也就是集合存放元素的个数);

    源码

    //如果是第一次添加元素
    public boolean add(E e) {
        //private int size; //size = 0;
        //调用ensureCapacityInternal(int minCapacity)方法
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    
    //minCapacity = 1;
    private void ensureCapacityInternal(int minCapacity) {
        //调用calculateCapacity(Object[] elementData, int minCapacity)方法
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
    
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        //判断是不是默认空的Object数组
        //如果是进入选择一个数组容量
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //private static final int DEFAULT_CAPACITY = 10;
            //minCapacity = 1;
            //所以第一次添加元素时,自动进行扩容,默认扩充容量是10
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }
    

    3、扩容

    //当前一次扩容的数组容量不足时(放满10个元素,再想添加一个元素,容量不足),开始进行动态扩容;
    //每次扩容,是之前一次扩容后的数组容量的1.5倍(即:每次都在前一次数组容量的基础上,增加一半-右移1位);
    //最大容量Integer.MAX_VALUE - 8,即2^31-8
    
    //扩容方法
    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) //如果新数组的容量大于最大值,将数组的容量设置为Integer.MAX_VALUE - 8
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        //private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
    }
    

    4、ArrayList初始化

    基于多态创建ArrayList集合对象

    List<Object> list = new ArrayList<>(); // 推荐
    Collection collection = new ArrayList();
    ArrayList arrayList = new ArrayList();
    List<Integer> intList = new ArrayList<>(); //可以使用泛型,指定存放数据的类型
    

    5、常用方法

    方法 说明
    add(Object obj) 添加元素
    add(int index, E element) 指定下标添加元素
    remove(int index) 移除元素
    get(int index)) 获取元素
    size() 集合元素个数
    contains(Object o) 是否包含某元素
    isEmpty() 集合是否为空

    5.1 add(Object obj)

    //添加元素方法:add(Object obj),每次添加元素都是自动添加到数组的末尾,元素下标值从0开始,跟数组一致;
    //可以添加重复值;
    //可以添加null值;
    

    5.2 add(int index, E element)

    //指定下标添加元素和删除元素,执行效率比较低;
    

    5.3 remove(int index)

    // 根据下标删除,如果重复,只能删除第一个出现的;
    

    5.4 get(int index))

    // 获取元素方法:get(下标值),只能通过下标取值;
    //当访问下标值超出了集合元素的最大下标值,报下标越界异常:java.lang.IndexOutOfBoundsException
    // 可用的下标值的范围:最小值是0,最大值是集合元素的个数 - 1
    

    5.5 size()

    // 获取集合中元素个数方法:size();
    

    5.6 contains(Object o)

    // 判断list集合中,是否包含某个元素方法:contains(查找元素值),返回true,代表存在,返回false,代表不存在;
    

    5.7 isEmpty()

    // 判断list集合是否为空方法:isEmpty(),返回true代表没有元素,空的,返回false,代表有元素,不是空的
    // 底层就是通过集合中元素个数size == 0 判断,所以也可以使用size() == 0判断集合非空
    

    源码

    public boolean isEmpty() {
        return size == 0;
    }
    

    5.8 clear()

    //清空list集合方法:clear(),清除集合中的所有元素
    

    源码

    ublic void clear() {
        modCount++;
    
        // clear to let GC do its work
        for (int i = 0; i < size; i++) //一次将数组赋值为null;
        elementData[i] = null;
    
        size = 0; //设置数组长度为0;
    }
    

    5.9 toArray()

    // list集合一步转换为数组方法:toArray(),返回的是Object类型数组
    

    6、数组转换成集合

    Arrays.asList(目标数组)

    String[] strArrays = {"奥迪", "奔驰", "宝马"};
    List<String> strList1 = Arrays.asList(strArrays);
    System.out.println(strList1); //[奥迪, 奔驰, 宝马]
    

    7、遍历

    List<String> strList = new ArrayList<>();
    strList.add("Audi");
    strList.add("Benz");
    strList.add("Bmw");
    strList.add("Audi");
    
    //for循环
    for (int i = 0; i < strList.size(); i++) {
        System.out.println("汽车品牌:" + strList.get(i));
    }
    
    //迭代器
    //Iterator迭代器,只能通过集合获取,不可以重复使用,迭代结束,迭代器就失效,如果想再次使用,需要重新获取
    Iterator<String> iterator = strList.iterator();
    // 迭代器遍历,使用while,不知道其中元素个数
    while(iterator.hasNext()){
        System.out.println("汽车品牌:" + iterator.next());
    }
    

    运行结果:

    汽车品牌:Audi
    汽车品牌:Benz
    汽车品牌:Bmw
    汽车品牌:Audi
    

    8、Vector(线程安全)

    //Vector,底层数据结构是和ArrayList一致的,都是对象数组,但是它的操作是线程安全的,每个方法都带有synchronized同步;
    // 默认初始容量是10,可以自定义,但是不能小于0,默认每次扩容是前一次容量的一倍,扩容的数量也是可以指定的,如果指定,每次都是在前一次基础上扩容指定的数量
    
  • 相关阅读:
    Maven项目管理(一)
    (15)Blender源码分析之闪屏窗口显示菜单功能
    报错:The supplied javaHome seems to be invalid. I cannot find the java executable
    【杰理AC696X】外挂FLASH音乐播放及Bin文件制作
    【Unity】U3D TD游戏制作实例(五)防御塔设计:对象排序、锁定敌人、攻击敌人、防御塔特色功能实现
    Vue中Vue router和axios的封装使用。
    unity【动画】操作_角色动画控制器 c#
    MES集成 | 集成标准不统一?看得帆云iPaaS怎么应对
    B站画质补完计划(3):智能修复让宝藏视频重焕新生
    oracle学习47-oracle删除非空表空间
  • 原文地址:https://www.cnblogs.com/xiaoqigui/p/16390758.html