ArrayList类源码浅析(一)

1、首先来看一下ArrayList类中的字段

可以看出,ArrayList维护了一个Object数组,默认容量是10,size记录数组的长度;

2、ArrayList提供了三个构造器:ArrayList(int initialCapacity),ArrayList(),ArrayList(Collection<? extends E> c)

带int参数的构造是指定ArrayList的大小,无参的构造函数,Object[]初始化为一个空数组,重点来讨论接受一个Colection参数的构造器,先看看源码

传入的Collection对象得到一个数组,赋值给elementData,然后再判断是否是Object[]类型,如果不是,则在copyOf方法里面生成一个Object[]数组,

返回并且赋值给elementData;Arrays.copyOf方法有多个重载方法,但是底层都是统一的调用System类中的arraycopy方法,这是一个系统的方法;

3、get(int index)、set(int index, E element)、remove(int index)方法

涉及到下标的操作,调用这三个方法,都会检查下标index是否合法,如果index>size,直接会抛出异常;

这两个方法都会调用一个公用的方法elementData(index),是根据下标index获取数组中的元素;

4、add(E e)、add(int index, E element)方法

在调用这两个方法的时候,都会调用ensureCapacityInternal(size + 1),来进行数组的扩容操作;

数组扩容分为两路:

  1、如果是调用无参的构造函数创建的ArrayList对象,那么是第一次扩容,第一次扩容的数组大小为 final int DEFAULT_CAPACITY = 10;

  2、如果ArrayList对象中数组已经存在,并且size+1超过了数组的长度,那么也需要进行数组的扩容;

  这时因为elementData数组中已经有值,扩容时,数组长度增加为扩容之前的1.5倍,把原来数组的数据复制到新的数组中去;

  这里就存在一个问题,如果频繁的去执行add操作,那么就会进行频繁的数组复制;

  如果数组有100万个元素,那么就是有大量的是、内存复制操作,对于GC的压力会比较大,同时这个操作的效率也会非常低;

  所以,必要的时候,可以指定数组的大小,使用ArrayList(int initialCapacity)构造方法去构造ArrayList对象,一定程度上能提高效率;

5、remove(Object o)这个方法可以看一下

这个方法是从ArrayList中删除一个元素,因为ArrayList里面可以存在null元素,所以在删除时,需要分开处理;

如果o为空,执行一个条件块,如果不为空执行另外一个条件块;

他们调用共用的删除方法:fastRemove(int index),这个方法在删除时,也是进行数组的复制;

时间: 2024-12-15 15:29:46

ArrayList类源码浅析(一)的相关文章

ArrayList类源码浅析(三)

1.看一个示例 运行上述代码,抛出一个异常: 这是一个典型的并发修改异常,如果把上述代码中的125行注释,把126行打开,运行就能通过了: 原因: 1)因为在迭代的时候,使用的是Itr类的对象,在调用hasNext()方法的时候,只要cursor和szie不相等就返回true: 2)在Itr类中存在一个属性字段:expectedModCount,每次调用next()方法的时候都会检查expectedModCount和modCount是否相等, 如果不相等,就会抛出异常: 3)调用Itr类的rem

Long类源码浅析

1.Long类和Integer相类似,都是基本类型的包装类,类中的方法大部分都是类似的: 关于Integer类的浅析可以参看:Integer类源码浅析 2.这里主要介绍一下LongCache类,该缓存类比Integer的缓存类,实现更简单 1 private static class LongCache { 2 private LongCache(){} 3 4 static final Long cache[] = new Long[-(-128) + 127 + 1]; 5 6 static

ArrayList类源码解析

ArrayList特点: 1.内部通过数组实现 2.删除.插入元素需要大量移动元素 3.默认存储容量是null,需要增加容量时候,默认增加的容量等于原始ArrayList的容量 4.没有实现同步方法,多线程的时候,线程不安全,效率较高 5.存储元素的顺序就说加入集合中的顺序,方便指定index访问元素 所在包 package java.util; 继承AbstractList抽象类 实现List.RandomAccess.Cloneable.java.io.Serializable public

java.lang.Byte 类源码浅析

Byte 类字节,属于Number. 1 public final class Byte extends Number implements Comparable<Byte> { 2 3 /** 4 * A constant holding the minimum value a {@code byte} can 5 * have, -2<sup>7</sup>. 6 */ 7 public static final byte MIN_VALUE = -128; 8 9

Jdk1.8 之 Integer类源码浅析

先看一下它的继承.实现关系: public final class Integer extends Number implements Comparable<Integer> Number是个抽象类,大概包含六个抽象方法,都是用来类型转换的 具体代码如下:public abstract class Number implements java.io.Serializable { public abstract int intValue(); public abstract long longV

Android应用Loaders全面详解及源码浅析

1 背景 在Android中任何耗时的操作都不能放在UI主线程中,所以耗时的操作都需要使用异步实现.同样的,在ContentProvider中也可能存在耗时操作,这时也该使用异步操作,而3.0之后最推荐的异步操作就是Loader.它可以方便我们在Activity和Fragment中异步加载数据,而不是用线程或AsyncTask,他的优点如下: 提供异步加载数据机制: 对数据源变化进行监听,实时更新数据: 在Activity配置发生变化(如横竖屏切换)时不用重复加载数据: 适用于任何Activit

【转】ArrayList其实就那么一回事儿之源码浅析

转自:http://www.cnblogs.com/dongying/p/4013271.html?utm_source=tuicool&utm_medium=referral ArrayList 算是常用的集合之一了,不知作为javaner的你有没在百忙之中抽出一点时间看看ArrayList的源码呢. 如果看了,你会觉得其实ArrayList其实就那么一回事儿,对吧,下面就看看ArrayList的部分源码吧. public class ArrayList<E> extends Abs

ArrayList其实就那么一回事儿之源码浅析

ArrayList 算是常用的集合之一了,不知作为javaner的你有没在百忙之中抽出一点时间看看ArrayList的源码呢. 如果看了,你会觉得其实ArrayList其实就那么一回事儿,对吧,下面就看看ArrayList的部分源码吧. 1 public class ArrayList<E> extends AbstractList<E> 2 implements List<E>, RandomAccess, Cloneable, java.io.Serializabl

Gradle 庖丁解牛(构建源头源码浅析)

1 背景 陆陆续续一年多,总是有人问 Gradle 构建,总是发现很多人用 Gradle 是迷糊状态的,于是最近准备来一个"Gradle 庖丁解牛"系列,一方面作为自己的总结,一方面希望真的能达到标题所示效果,同时希望通过该系列达到珍惜彼此时间的目的,因为目前市面上关于 Gradle 的教程都是在教怎么配置和怎么编写插件,很少有说明 Gradle 自己到底是个啥玩意的,还有是如何工作的,本系列以官方 release 3.4 版本为基础. 废话不多说,标题也表明了本篇所总结的内容 --