大佬理解->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,默认每次扩容是前一次容量的一倍,扩容的数量也是可以指定的,如果指定,每次都是在前一次基础上扩容指定的数量

Java集合框架(一)-ArrayList的更多相关文章

  1. Java集合框架之ArrayList浅析

    Java集合框架之ArrayList浅析 一.ArrayList综述: 位于java.util包下的ArrayList是java集合框架的重要成员,它就是传说中的动态数组,用MSDN中的说法,就是Ar ...

  2. Java——集合框架之ArrayList,LinkedList,迭代器Iterator

    概述--集合框架 Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(Java Collection ...

  3. java集合框架03——ArrayList和源码分析

    最近忙着替公司招人好久没写了,荒废了不好意思. 上一章学习了Collection的架构,并阅读了部分源码,这一章开始,我们将对Collection的具体实现进行详细学习.首先学习List.而Array ...

  4. java集合框架05——ArrayList和LinkedList的区别

    前面已经学习完了List部分的源码,主要是ArrayList和LinkedList两部分内容,这一节主要总结下List部分的内容. List概括 先来回顾一下List在Collection中的的框架图 ...

  5. 深入理解java集合框架之---------Arraylist集合 -----添加方法

    Arraylist集合 -----添加方法 1.add(E e) 向集合中添加元素 /** * 检查数组容量是否够用 * @param minCapacity */ public void ensur ...

  6. java集合框架之ArrayList

    参考http://how2j.cn/k/collection/collection-arraylist/363.html 使用数组的局限性 一个长度是10的数据:Hero[] heroArr=new ...

  7. 深入理解java集合框架之---------Arraylist集合 -----构造函数

    ArrayList有三个构造方法 ArrayList有三个常量 1.private transient Object[] elementData (数组); 2.private int size (元 ...

  8. java集合框架之ArrayList与LinkedList的区别

    参考http://how2j.cn/k/collection/collection-arraylist-vs-linkedlist/690.html#nowhere ArrayList和LinkedL ...

  9. 深入理解java集合框架之---------Arraylist集合

    ArrayList简介 ArrayLIst是动态数组,用MSDN的说法就是Array的复杂版本,它提供了动态的增加和减少元素,实现了Collection和List接口,可以灵活的设置数组的大小,要注意 ...

随机推荐

  1. LC-202

    编写一个算法来判断一个数 n 是不是快乐数. 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和. 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 ...

  2. 帝国cms7.5忘记登录密码以及多次登录失败被锁定终极解决办法

    其实网上很多忘记登录密码的解决方法都是相对于7.5版本以下的,在7.5的版本里根本不适用,今天小编主要给大家说的是针对帝国cms7.5忘记登录密码正确的解决办法. 前提是你能登陆服务器: 一.忘记登录 ...

  3. Unity中制作血条2.0

    ##1.血量显示 不必像之前那样添加Slider组件 直接创建Image 在添加Source Image之后,将Image Type 修改为Filled 通过修改Fill Mode就可以显示不同效果 ...

  4. Postman大势已去

    作为一名前端,日常开发过程中除了写业务代码,前后端联调更是重要的一环.但这一环却往往是整个开发中最繁琐也最累人的一环.任谁都想早点下班,然而提升联调效率并不是个纯技术相关的问题,而是需要有良好工作流程 ...

  5. 用js实现倒计时效果

    首先获得两个时间的时间戳 var newdate = new Date('2021-01-22 21:25:00').getTime(); var olddate = new Date().getTi ...

  6. Codeforces Round #752 (Div. 2) A B C

    Problem - A - Codeforces Problem - B - Codeforces Problem - C - Codeforces A. Era 每个a[i] - i 表示的是当前a ...

  7. 面试官:RabbitMQ过期时间设置、死信队列、延时队列怎么设计?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 RabbitMQ我们经常的使用, ...

  8. JuiceFS 缓存预热详解

    缓存预热是一个比较常见的概念,相信很多小伙伴都有所了解.对于 JuiceFS 来说,缓存预热就是将需要操作的数据预先从对象存储拉取到本地,从而获得与使用本地存储类似的性能表现. 缓存预热 JuiceF ...

  9. Java包装类,基本的装箱与拆箱

    我的博客 何为包装类 将原始类型和包装类分开以保持简单.当需要一个适合像面向对象编程的类型时就需要包装类.当希望数据类型变得简单时就使用原始类型. 原始类型不能为null,但包装类可以为null.包装 ...

  10. 01. 树莓派初始配置——ssh连接使用root用户登录

    ssh连接使用root用户登录 普通的"pi"用户没有权限访问某些文件夹,或者对它们只有只读功能.部分操作需要在每条命令前都要加上"sudo",非常不方便.切换 ...