`
geeksun
  • 浏览: 965274 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ArrayList源码解析

 
阅读更多

       ArrayList和HashMap、LinkedList一样,是常用的数据结构。ArrayList提供了一个动态数组,弥补了数组的长度固定,增加元素操作消耗大的不足。但因为ArrayList存储了对象数组,构造对象也造成了性能开销,所以相对布言,如果数组的长度可知,使用数组的效率最高,反之则可使用ArrayList。

 ArrayList内部使用Object[]存储数据

    private transient Object[] elementData;

 ArrayList使用Obect数组elementData来存储数据,这样可以存储任意类型的数据。

 构造函数

    public ArrayList() {
	this(10);
    }

 默认构造函数的数组的容量为10。

 ArrayList添加元素

    public boolean add(E e) {
	ensureCapacity(size + 1);  // Increments modCount!!
	elementData[size++] = e;
	return true;
    }

 添加元素时,元素添加到ArrayList容器的尾部。

 在添加元素之前,先判断数组的容量是否需要扩容ensureCapacity(size+1),传的参数是当前数组的size+1。

确保ArrayList容器容量

    public void ensureCapacity(int minCapacity) {
	modCount++;
	int oldCapacity = elementData.length;
	if (minCapacity > oldCapacity) {
	    Object oldData[] = elementData;
	    int newCapacity = (oldCapacity * 3)/2 + 1;
    	    if (newCapacity < minCapacity)
		newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
	}
    }

 在ensureCapacity方法中,先把参数(新索引值)minCapacity与数组容器的原长度oldCapacity做比较,如果参数minCapacity大于原长度,就说明数组已经饱和,需要进行扩容。

扩容的具体实现是把原来的长度增加50%再增加1,然后,把旧数组的数据拷贝到新数组里(使用System.arrayCopy()实现)。

在指定位置(index)添加元素

    public void add(int index, E element) {
	if (index > size || index < 0)
	    throw new IndexOutOfBoundsException(
		"Index: "+index+", Size: "+size);

	ensureCapacity(size+1);  // Increments modCount!!
	System.arraycopy(elementData, index, elementData, index + 1,
			 size - index);
	elementData[index] = element;
	size++;
    }

 实现流程也是先判断数组需不需要扩容,然后把从index往后面的数组元素,向后移动一位。再把index位置的数组元素的引用赋予要插入的元素。

查找指定位置(index)的元素

    public E get(int index) {
	RangeCheck(index);

	return (E) elementData[index];
    }

 查找元素的方法比较简单,先是查看索引index值是否越界,如果在范围之内,直接返回数组的该索引元素。

从数组的指定位置index删除元素

    public E remove(int index) {
	RangeCheck(index);

	modCount++;
	E oldValue = (E) elementData[index];

	int numMoved = size - index - 1;
	if (numMoved > 0)
	    System.arraycopy(elementData, index+1, elementData, index,
			     numMoved);
	elementData[--size] = null; // Let gc do its work

	return oldValue;
    }

 在ArrayList中删除指定位置的元素时,如果这个index不是数组的最大下标位置,就把index之后的所有元素向前移动一位,来填充index位置的元素移除后的空白。

总结:

        ArrayList是一个动态数组数据结构,可以灵活地添加元素,查找性能好,而在指定位置添加和删除元素时性能下降,因为要移动数组的数据。所以ArrayList适用于查找多,而在数组内指定位置操作少的场景。

 

分享到:
评论

相关推荐

    第二章 ArrayList源码解析1

    第二章 ArrayList源码解析 ArrayList是Java集合框架中的一种动态数组,它继承自AbstractList,并实现了List接口。ArrayList主要用于存储可变大小的对象列表,它的核心是通过一个Object类型的数组elementData来实现...

    Java 集合框架(2-9)-Collection - ArrayList 源码解析.pdf

    《Java集合框架(2-9)-Collection - ArrayList 源码解析》 ArrayList是Java集合框架中的一个重要组件,它属于List接口的实现类,提供了一种动态数组的逻辑视图。ArrayList以高效、灵活的方式存储和操作对象序列,是...

    ArrayList源码解析(数据结构及底层实现)(csdn)————程序.pdf

    在深入源码解析之前,先了解一下 ArrayList 的基本操作和特点。 ArrayList 的默认容量是 10,这意味着当你创建一个新的 ArrayList 实例时,它会预分配一个长度为 10 的数组。当你向 ArrayList 添加元素时,如果数组...

    ArrayList源码Jdk1.8

    ### ArrayList源码解析(JDK 1.8) #### 概述 `ArrayList`是Java集合框架中的一个核心组件,它提供了动态数组的功能。与固定大小的数组不同,`ArrayList`可以随着元素的增加而自动扩展其容量。在JDK 1.8中,`...

    ArrayList 源码深度解析

    ArrayList 源码深度解析 一、重新认识ArrayList 什么是ArrayList? ArrayList是基于数组实现的List类,封装了一个动态再分配的Object数组,以达到可以动态增长和缩减的索引序列。 长啥样? 如图,是一个长度为6,...

    ArrayList源码分析

    本篇文章将深入探讨ArrayList的源码,了解其内部实现机制,以及在实际编程中如何有效地使用ArrayList。 1. **ArrayList的构造函数** ArrayList提供了多个构造函数,包括无参构造、指定容量构造和初始化容量并赋值...

    Java中ArrayList类的源码解析

    Java中ArrayList类的源码解析 ArrayList是Java中最常用的集合类之一,它实现了List接口,继承自AbstractList抽象类。在ArrayList中,我们可以看到它的源码实现了Iterable接口、List接口和Collection接口。下面我们...

    java——ArrayList-源码解析.docx

    ArrayList 是 Java 中一种常用的列表类,它是 List 接口的实现,基于动态数组的数据结构。ArrayList 的核心特性在于其能够动态地调整数组的大小以适应元素数量的变化,从而提供了比传统固定大小数组更为灵活的使用...

    ArrayList扩容机制源码解析.md

    本资源根据个人学习和总结,主要介绍Java中ArrayList扩容机制源码的解析,主要包含文字和代码等内容,以源码的形式进行分析,详细介绍了ArrayList扩容机制的整个流程,特此将该资源分享

    源码解析jdk7.0集合:ArrayList的底层实现原理.pdf

    在探讨 JDK 7.0 中 ArrayList 的底层实现原理之前,首先需要了解 ArrayList 作为 Java 集合框架中 List 接口的动态...此外,了解 ArrayList 的源码还有助于深入理解 Java 集合框架的设计哲学及面向对象设计的诸多原则。

    硬核ArrayList源码分析,答应我每天看一遍好么

    《硬核ArrayList源码分析——深入理解Java集合框架》 ArrayList是Java集合框架中的一个重要组成部分,它是基于动态数组实现的列表。在Java 1.8版本中,ArrayList的实现细节和内部工作原理对于理解其性能和行为至关...

    深入Java集合ArrayList的源码解析

    《深入Java集合ArrayList的源码解析》 ArrayList作为Java集合框架中的重要成员,其底层数据结构和操作方式对于理解Java编程至关重要。这篇文章将从ArrayList的基本属性、构造方法、增删改查的操作以及扩容机制等...

    ArrayList-LinkedList-源码.rar

    《ArrayList与LinkedList源码解析》 在Java编程中,ArrayList和LinkedList是两种常见的动态数组,它们都是Java集合框架的一部分,提供了对元素存储和操作的功能。本篇将深入探讨ArrayList和LinkedList的内部实现...

    ArrayList动态删除 自定义Adapter (附源码)

    本文将深入探讨如何在ListView中实现动态删除功能,并提供相关的源码解析。 首先,ArrayList是一个动态数组,允许我们在运行时添加、删除和修改元素。在ListView中,我们通常使用自定义Adapter来连接数据源(如...

    从原码解析ArrayList

    本文将从ArrayList的源码出发,详细解析其底层实现、默认初始容量、RandomAccess接口以及添加和获取元素的方法,进一步探讨ArrayList的特点。 1. **ArrayList的默认初始容量** ArrayList在初始化时,默认的容量...

    集合类底层源码解析汇总

    java所有集合类底层源码解析汇总,包括ArrayList、HashMap、HashSet、LinkedList、TreeMap、HashSet、ConcurrentHashMap等集合框架的底层实现源码大白话解读。

    Java源码解析ArrayList及ConcurrentModificationException

    } }这两个构造函数分别用于创建一个默认容量为10的ArrayList和指定初始容量的ArrayList。当传入的初始容量为0时,会使用EMPTY_ELEMENTDATA,而不是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,因为此时不打算立即扩容。...

    Java源码解析——看优秀源码最能使人进步

    Java源码解析——看优秀源码最能使人进步 Java源码解析是一种深入了解JDK源码的方式,适合那些想深入了解JDK源码的人。通过对JDK源码的解析,可以让开发者更好地理解Java语言的底层逻辑,从而写出更加高效、稳定的...

Global site tag (gtag.js) - Google Analytics