JDK8集合类源码解析 - ArrayList
ArrayList主要要注意以下几点:
1构造方法
2添加add(E e)
3 获取 get(int index)
4 删除 remove(int index) , remove(Object o)
5 判断是否存在 contains(Object o)
6 遍历
======================================
底层采用数组实现。
1构造方法
有三个 分别是 指定数组大小;不指定(创建一个空的,添加元素的时候再扩容);从一个集合创建
这里顺便说下集合的继承关系
Collection
|--List
|--ArrayList
|--Vector
|--LinkedList
|--Set
|--HashSet
|--TreeSet
2添加add(E e)
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 先判断容量够不够
//添加到末尾
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) { //空就创建一个长度为10的数组
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
} ensureExplicitCapacity(minCapacity);
} private void ensureExplicitCapacity(int minCapacity) {
modCount++; //操作计数+1 用于在遍历的时候判断是否有添加或者删除操作
if (minCapacity - elementData.length > 0)
grow(minCapacity);//扩容
} private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//变成原来的1.5倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)//如果新容量 MAX_ARRAY_SIZE还大 那么新容量就设置为Integer.MAX_VALUE
newCapacity = hugeCapacity(minCapacity);
//复制数据
elementData = Arrays.copyOf(elementData, newCapacity);
}
3 获取 get(int index)
public E get(int index) {
rangeCheck(index); //看数组是否越界
return elementData(index);
}
4 删除 remove(int index) , remove(Object o)
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1; //需要移动的元素的个数
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,numMoved);//从删除的元素到最后的元素全部前移
elementData[--size] = null; // 方便gc回收
return oldValue;
}
remove(Object o) 先遍历找到该元素,然后在删除 ,删除方法和上面的方法类似,需要移动数组(如果不是最后一个元素的话)
5 判断是否存在 contains(Object o)
//遍历 找到了就返回下标 不然返回 -1
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
6遍历
int cursor; // 遍历标志位
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount; public boolean hasNext() {
return cursor != size;
} @SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
} public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification(); try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
注意两点: 1遍历的时候 如果要删除元素 要使用Iterator
2只有调用了next才能调用remove
最佳实践
1如果能够预知集合大小,创建的时候最好使用指定大小的构造函数,能够提高性能(没有了扩容)
2线程不安全,多线程环境建议使用CopyOnWriteArrayList
3遍历集合 如果要删除元素 要使用Iterator
4底层基于数值实现,增删慢 获取快(仅限于下标方式)
JDK8集合类源码解析 - ArrayList的更多相关文章
- JDK8集合类源码解析 - HashSet
HashSet 特点:不允许放入重复元素 查看源码,发现HashSet是基于HashMap来实现的,对HashMap做了一次“封装”. private transient HashMap<E,O ...
- JDK8集合类源码解析 - LinkedList
linkedList主要要注意以下几点: 1构造器 2 添加add(E e) 3 获取get(int index) 4 删除 remove(E e),remove(int index) 5 判断对象 ...
- JDK8集合类源码解析 - HashMap
java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是HashMap.Hashtable.LinkedHashMap和TreeMap HashMap ...
- Java集合类源码解析:Vector
[学习笔记]转载 Java集合类源码解析:Vector 引言 之前的文章我们学习了一个集合类 ArrayList,今天讲它的一个兄弟 Vector.为什么说是它兄弟呢?因为从容器的构造来说,Vec ...
- Java集合类源码解析:HashMap (基于JDK1.8)
目录 前言 HashMap的数据结构 深入源码 两个参数 成员变量 四个构造方法 插入数据的方法:put() 哈希函数:hash() 动态扩容:resize() 节点树化.红黑树的拆分 节点树化 红黑 ...
- Java集合类源码解析:ArrayList
目录 前言 源码解析 基本成员变量 添加元素 查询元素 修改元素 删除元素 为什么用 "transient" 修饰数组变量 总结 前言 今天学习一个Java集合类使用最多的类 Ar ...
- Java集合类源码解析:AbstractMap
目录 引言 源码解析 抽象函数entrySet() 两个集合视图 操作方法 两个子类 参考: 引言 今天学习一个Java集合的一个抽象类 AbstractMap ,AbstractMap 是Map接口 ...
- Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap
声明:以下源代码使用的都是基于JDK1.8_112版本 1. ArrayList源码解析 <1. 集合中存放的依然是对象的引用而不是对象本身,且无法放置原生数据类型,我们需要使用原生数据类型的包 ...
- Java集合类源码解析:LinkedHashMap
前言 今天继续学习关于Map家族的另一个类 LinkedHashMap .先说明一下,LinkedHashMap 是继承于 HashMap 的,所以本文只针对 LinkedHashMap 的特性学习, ...
随机推荐
- bpm 学习笔记一
名词解释: DC: Development Component WD:Web Dynpro Keep DC Local for Now
- Ubuntu 16.04 LTS network DIASBLED解决办法
问题 昨天正浏览着网页,突然无法连接.但右上角的wifi信号显示仍然是连接状态.于是我尝试断开再重新连接一次,没想到刚断开就报了个内部错误,然后wifi图标直接消失了.重启后虽然有wifi图标,但无法 ...
- jquery mobil 和页面适应
<meta name="viewport" content="width=device-width" />
- java发送http连接
原生方式:@转载文章 import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamRead ...
- jmeter操作数据库,分布式,在Linux上运行
jmeter操作数据库: 1.在测试计划中导入数据库jar包 2.添加链接数据库信息 3.mysql:jdc:mysql://192.168.1.116:3307/bugfree?allowMulti ...
- Linux用7zip解压缩分卷文件
背景:在服务器迁移过程中,有大量非结构化文件(主要是office文档和图片),目录结构太大,高达80-100G,传输耗时且容易受网络 等其他原因意外中断,以致于传输失败,于是采用分卷压缩,即使传输失败 ...
- js 变量大小写
js对变量是区分大小写的.完毕.
- mySLQ数据库 练习题
MySQL 练习题1 DROP TABLE IF EXISTS `liuyan`; CREATE TABLE `liuyan` ( `id` int(11) NOT NULL AUTO_INCREME ...
- sharpsvn 继续,解决文件locked 问题,
方法中少个方法就会出现一些问题. 比如进行了断线测试,结果再操作时就出现了文件被锁的情况,最终查了官网的论坛,才得以解决 How to unlock if the working copy is lo ...
- 18.Mysql SQL优化
18.SQL优化18.1 优化SQL语句的一般步骤 18.1.1 通过show status命令了解各种SQL的执行频率show [session|global] status; -- 查看服务器状态 ...