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的更多相关文章

  1. JDK8集合类源码解析 - HashSet

    HashSet 特点:不允许放入重复元素 查看源码,发现HashSet是基于HashMap来实现的,对HashMap做了一次“封装”. private transient HashMap<E,O ...

  2. JDK8集合类源码解析 - LinkedList

    linkedList主要要注意以下几点: 1构造器 2 添加add(E e) 3 获取get(int index) 4 删除 remove(E e),remove(int index) 5  判断对象 ...

  3. JDK8集合类源码解析 - HashMap

    java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是HashMap.Hashtable.LinkedHashMap和TreeMap HashMap ...

  4. Java集合类源码解析:Vector

    [学习笔记]转载 Java集合类源码解析:Vector   引言 之前的文章我们学习了一个集合类 ArrayList,今天讲它的一个兄弟 Vector.为什么说是它兄弟呢?因为从容器的构造来说,Vec ...

  5. Java集合类源码解析:HashMap (基于JDK1.8)

    目录 前言 HashMap的数据结构 深入源码 两个参数 成员变量 四个构造方法 插入数据的方法:put() 哈希函数:hash() 动态扩容:resize() 节点树化.红黑树的拆分 节点树化 红黑 ...

  6. Java集合类源码解析:ArrayList

    目录 前言 源码解析 基本成员变量 添加元素 查询元素 修改元素 删除元素 为什么用 "transient" 修饰数组变量 总结 前言 今天学习一个Java集合类使用最多的类 Ar ...

  7. Java集合类源码解析:AbstractMap

    目录 引言 源码解析 抽象函数entrySet() 两个集合视图 操作方法 两个子类 参考: 引言 今天学习一个Java集合的一个抽象类 AbstractMap ,AbstractMap 是Map接口 ...

  8. Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap

    声明:以下源代码使用的都是基于JDK1.8_112版本 1. ArrayList源码解析 <1. 集合中存放的依然是对象的引用而不是对象本身,且无法放置原生数据类型,我们需要使用原生数据类型的包 ...

  9. Java集合类源码解析:LinkedHashMap

    前言 今天继续学习关于Map家族的另一个类 LinkedHashMap .先说明一下,LinkedHashMap 是继承于 HashMap 的,所以本文只针对 LinkedHashMap 的特性学习, ...

随机推荐

  1. ServiceWork的五种状态

    [ServiceWork的五种状态] installing.installed.activating.activated.redundant 参考:https://developer.mozilla. ...

  2. Java volatile关键字的用法

    volatile不能解决同步问题 如果想要理解volatile关键字的作用不得不先了解Java内存模型 摘抄一下来自百度百科的话 在本次线程内,当读取一个变量时,为提高存取速度,编译器优化时有时会先把 ...

  3. 【Scheme】元循环求值

    #lang scheme (require rnrs/base-6) (require rnrs/mutable-pairs-6) (define (eval exp env) (cond ((sel ...

  4. 【scrapy】其他问题2

    今天爬取豆瓣电影的是时候,出现了两个问题: 1.数据无法爬取并输出Retrying <GET https://movie.douban.com/robots.txt> 看起来像是被拦截了. ...

  5. poj2912(带权并查集+枚举)

    题目链接:http://poj.org/problem?id=2912 题意:给n个人,m组关系,玩石头剪刀布的游戏,n个人中除一个人judge以外,其他人属于3个group(即石头.剪刀.布),他们 ...

  6. CentOS 下搭建Gitlab

    centos7安装部署gitlab服务器   我这里使用的是centos 7 64bit,我试过centos 6也是可以的! 1. 安装依赖软件 yum -y install policycoreut ...

  7. Hdu1805-Expression(表达式树模版题+层序遍历树+栈的基本应用)

    2018-11-23-02:27:37 原题链接 题目描述: 题目一目了然. 本题思路: 本题很容易能想到是构建表达式树然后按照层序逆序输出即可. AC代码: #include <cstdio& ...

  8. pep8 && pep20

    pep8(部分,遇到问题再补充) 1.不建议使用tab键来空格,避免不必要的空格.操作符左右各加一个空格,函数默认参数使用的赋值符左右省略空格. 2.类和top-level函数定义之间空两行:类中的方 ...

  9. ActiveMQ之整合spring

    ActiveMQ可以轻松的与Spring进行整合,Spring提供了一系列的接口类,非常的好用! 比如异步消息数据.异步发送邮件.异步消息查询等 <dependency> <grou ...

  10. win静态库动态库

    静态链接库: #include "..\lib.h" #pragma comment(lib,"..\\debug\\libTest.lib") //指定与静态 ...