源码分析

具体关系:

  1. 我们平时常用需要掌握的:
    ArrayList,LinkedList,HashMap,HashSet。。。

  2. List,Set,Map对比

接口 子接口 是否有序 是否允许元素重复
Collection
List ArrayList
LinkedList
Vector
Set AbstractSet
HashSet
TreeSet 是(用二叉排序树)
Map AbstractMap 使用key-value来映射和存储数据,key必须唯一,value可以重复
HashMap
TreeMap 是(用二叉排序树) 使用key-value来映射和存储数据,key必须唯一,value可以重复

ArrayList详解

内部主要是数组实现
1. 内部变量

    /*** 初始化容量*/private static final int DEFAULT_CAPACITY = 10;/*** 用于空实例的共享空数组实例*/private static final Object[] EMPTY_ELEMENTDATA = {};/*** 共享的空数组实例,用于默认大小的空实例。我们将其与EMPTY_ELEMENTDATA区别开来,以了解添加第一个元素时需要充气多少。*/private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};/*** 存储ArrayList的元素的数组缓冲区。 ArrayList的容量是此数组缓冲区的长度。添加第一个元素时,任何具有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的空ArrayList将被扩展为DEFAULT_CAPACITY。*/transient Object[] elementData; // non-private to simplify nested class access/*** ArrayList的大小(它包含的元素数)** @serial*/private int size;

2. 构造函数

// 构造一个具有指定初始容量的空列表。
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);}}// 构造一个初始容量为10的空列表
public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}// 构造一个包含指定*集合的元素的列表,其顺序由集合的迭代器返回。
public ArrayList(Collection<? extends E> c) {Object[] a = c.toArray();if ((size = a.length) != 0) {if (c.getClass() == ArrayList.class) {elementData = a;} else {elementData = Arrays.copyOf(a, size, Object[].class);}} else {// replace with empty array.elementData = EMPTY_ELEMENTDATA;}}

3. add 方法

// 将指定的元素追加到此列表的末尾。
public boolean add(E e) {ensureCapacityInternal(size + 1);  // 增加modCount!elementData[size++] = e;return true;}/ **
* 在列表中特定的位置新增特定的元素,移动当前在该位置的元素(如果有)并且右边的任何后续元素(将其索引添加一个)
*/
public void add(int index, E element) {rangeCheckForAdd(index); // 判断ensureCapacityInternal(size + 1);  // 增加modCount!System.arraycopy(elementData, index, elementData, index + 1, size - index);elementData[index] = element;size++;}// add和addAll使用的rangeCheck版本private void rangeCheckForAdd(int index) {if (index > size || index < 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);}private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;// 增加容量以确保它至少可以容纳最小容量参数指定的元素数。
private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 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);}

通过源码我们可以看出:
Arraylist在添加元素的时候,首先进行的是范围检查,防止其传入的参数小于0或者超过数组的size大小,再是和默认分配的大小值进行比较,如果大于默认大小就要进行扩容。扩容的时候首先把旧数组的大小提升1.5倍,成为新数组的大小值。同时也可以看到Arrylist的大小边界是Interger的最大值,这个数字是很大的:2147483647,也就是它的最大值是这么多,这个值足以我们程序员平常进行使用!在检查完毕和扩容完毕之后,就是要进行数组的拷贝了,我们开看一下System.arrayCopy()方法的源码:

public static native void arraycopy(Object src,  int  srcPos, Object dest,  int destPos, int length);

中可以看出,它是native修饰的,也就是说它是一个引用本地其他语言的代码库(windows就是.dll库)的方法,具体的源码我们不深究了,这里解释一下它的参数,src:你要从哪个数组复制,srcpos:要复制的位置起点 dest:要复制要哪个数组,destPos:要复制到的数组起始位置 lengh:复制的长度

System.arraycopy(elementData, index, elementData, index + 1,  size - index);

4. remove方法
我们看romove方法首先还是进行范围检查,然后用elementData()方法去找到指定数组元素中的值,再用size-index-1转为numMoved,接着进行再次自我复制。然后把size-1甚至设置为null。这样这个数组中元素就是null了。

public E remove(int index) {//根据指定位置移除元素rangeCheck(index);//范围检查modCount++;//修改次数+1E oldValue = elementData(index);//根据数组元素的位置找到旧值int numMoved = size - index - 1;if (numMoved > 0)//判断是否大于0System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size] = null; // return oldValue;//返回旧值}// 从此列表中删除第一次出现的指定元素,如果存在,则将其删除。如果列表不包含该元素,则不变。
public boolean remove(Object o) {if (o == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {fastRemove(index);return true;}} else {for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {fastRemove(index);return true;}}return false;}// 专用remove方法,跳过边界检查,并且不返回删除的值。
private void fastRemove(int index) {modCount++;int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index, numMoved);elementData[--size] = null; // clear to let GC do its work}

java的ArrayList分析相关推荐

  1. Java 集合 —— ArrayList 分析

    List 集合的特征: 有序 可以重复 可以随机访问(使用下标 添加,删除,访问) ArrayList 是 List 的实现类,所以 ArrayList 具有 List 的特征 ArrayList 是 ...

  2. 【Java源码分析】LinkedList源码分析

    类的定义如下 public class LinkedList<E> extends AbstractSequentialList<E> implements List<E ...

  3. (转)性能分析之-- JAVA Thread Dump 分析综述

    原文链接:http://blog.csdn.net/rachel_luo/article/details/8920596 最近在做性能测试,需要对线程堆栈进行分析,在网上收集了一些资料,学习完后,将相 ...

  4. Java针对ArrayList自定义排序的2种实现方法

    这篇文章主要介绍了Java针对ArrayList自定义排序的2种实现方法,结合实例形式总结分析了Java操作ArrayList自定义排序的原理与相关实现技巧,下面就和动力节点java学院小编一起来看看 ...

  5. java内存溢出分析工具:jmap使用实战

    java内存溢出分析工具:jmap使用实战 在一次解决系统tomcat老是内存撑到头,然后崩溃的问题时,使用到了jmap.  1 使用命令  在环境是linux+jdk1.5以上,这个工具是自带的,路 ...

  6. Java知识点总结(Java容器-ArrayList)

    Java知识点总结(Java容器-ArrayList) @(Java知识点总结)[Java, Java容器, JavaCollection, JavaList] ArrayList 底层实现是数组,访 ...

  7. Java API —— ArrayList类 Vector类 LinkList类

    1.ArrayList类 1)ArrayList类概述 · 底层数据结构是数组,查询快,增删慢 · 线程不安全,效率高 2)ArrayList案例 · 存储字符串并遍历 · 存储自定义对象并遍历 2. ...

  8. eclipse无法创建java虚拟机_手把手:Java内存泄漏分析Memory Analyzer Tool

    点击上方"IT牧场",选择"设为星标"点击上方"IT牧场",选择"设为星标"技术干货每日送达 阅读文本大概需要3分钟. ...

  9. Java中ArrayList的练习

    练习1:存储随机数 题目: 生成6个1~44之间的随机整数,添加到集合,并遍历集合. 思路: 1.需要存储6个数字,创建一个集合, 2.产生随机数,需要用到Random 3.用循环6次,来产生6个随机 ...

  10. java分析内存泄露工具_Eclipse Memory Analyzer(Java内存泄漏分析工具)

    概述 一个大型的Java项目也许从开发到测试结束并未发现一些大的问题,但是在生产环境中还是会出现一些非常棘手的问题,如内存泄漏,遇到这样的问题对于一个经验尚浅的开发人员来说难度非常大,好的一点是JVM ...

最新文章

  1. 华为P30Pro国外采用4根天线设计,为何国内却只有2根?
  2. 【PAT乙级】1036 跟奥巴马一起编程 (15 分)
  3. kFreeBSD有活过来的迹象?UbuntuBSD
  4. linux 显示器分辨率设置太小了,显示器不显示 如何在设置回来,当“显示设置”中的分辨率不可用时,如何使用xrandr设置自定义分辨率...
  5. 正则匹配中文 UTF-8 GBK
  6. 计算机网络聚合怎么设置,交换机的端口聚合如何配置
  7. endnote修改正文中参考文献标注_如何用Endnote在论文中插入参考文献
  8. 机器学习、深度学习概念术语的理解
  9. VB编辑器之代码颜色修改
  10. Ubuntu:back up whole system
  11. [工具推荐] IPv4 和 IPv6 网站测速工具
  12. Git 初接触 (四) Git的分支操作
  13. 搜狗输入法弹出搜狗新闻的解决办法
  14. Only the Paranoid Survive
  15. OA系统以项目管理为中心,为会计事务所打造内外协同一体化平台
  16. 大数据相关书籍(包含Java, Scala, R, Linux, Spark, Hadoop, Hive, Hbase, Sqoop, Flume, Strom)
  17. 筹码分布的计算方法笔记
  18. springboot实现几种常见登录(注册)方式
  19. C++ 如何加载lib
  20. RabbitMQ的简单使用

热门文章

  1. Ubuntu的LTS 18.04 安装FRR
  2. freeswitch 使用mysql替换默认的sqlite
  3. Makefile.am编写规则
  4. ffmpeg文档5:同步视频
  5. ffmpeg中的时间单位
  6. 文本分析用GUI界面显示
  7. 湖北省土壤有机质空间分布数据
  8. python学习(四)----函数
  9. c重启mysql_不重启Mysql修改root密码的方法
  10. 为什么哲学是最难的学科_为什么来读哲学系?