编辑推荐:

文章主要介绍ArrayList的继承关系,ArrayList的方法使用和源码解析,它提供了动态的增加和减少元素,实现了Collection和List接口,可以灵活的设置数组的大小,希望对您的学习有所帮助。

本文来自于csdn,由火龙果软件Delores编辑、推荐。

ArrayList简介

ArrayList就是动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了动态的增加和减少元素,实现了Collection和List接口,可以灵活的设置数组的大小。要注意的是ArrayList并不是线程安全的,因此一般建议在单线程中使用ArrayList。

ArrayList的继承关系

public class

ArrayList

extends AbstractList

implements List,

RandomAccess,Cloneable,Serializable

由上可知ArrayList继承AbstractList 并且实现了List和RandomAccess,Cloneable, Serializable接口。

ArrayList的方法使用和源码解析

①构造方法

//1-----------------------

public ArrayList() {

this(10);

//调用ArrayList(10)

默认初始化一个大小为10的object数组。

}

//2-------------------------

public ArrayList

(int initialCapacity) {

if (initialCapacity < 0)

throw new IllegalArgumentException

("Illegal

Capacity: "+

initialCapacity);

//如果用户初始化大小小于0抛异常,

否则新建一个用户初始值大小的object数组。

this.elementData =

new Object[initialCapacity];

}

//3--------------------------

public ArrayList

(Collection< extends E> c) {

elementData = c.toArray();

size = elementData.length;

// 当c.toArray返回的

不是object类型的数组时,进行下面转化。

if (elementData.getClass()

!= Object[].class)

elementData = Arrays.copyOf

(elementData, size,

Object[].class);

}

由上面三种构造方法可知,默认情况下使用ArrayList会生成一个大小为10的Object类型的数组。也可以调用ArrayList(int initialCapacity) 来初始化Object数组的大小。并且用户可以往ArrayList中传入一个容器只要这个容器是Collection类型的。调用ArrayList(Collection< extends E > c)接口的时候会将容器数组化处理并将这个数组值赋给Object数组。

实例:

public static

void main

(String[] args) {

ArrayList list_2=new

ArrayList(20);

//list_2中添加元素

for(int i=0;i<10;i++)

list_2.add(i);

ArrayList list_3=new

ArrayList(list_2);

//输出list_2中元素

for(Integer a:list_2)

System.out.print(a+" ");

//输出list_3中元素

for(Integer a:list_3)

System.out.print(a+" ");

}

//输出

/*

list_2 : 0 1 2 3 4 5 6 7 8 9

-----------------------

list_3 : 0 1 2 3 4 5 6 7 8 9

*/

②indexOf(Object o)方法

功能:查找某个元素在ArrayList中第一次出现的位置。

public int indexOf(Object

o) {

//ArrayList中的元素可以为null,

如果为null返回null的下标

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;

}

//如果没有找到对应的元素返回-1。

return -1;

}

对于indexof方法做几点说明:ArrayList中可以存放null元素,indexof是返回elementData数组中值相同的首个元素的下标,indexof中比较方法是equals而equals是比较元素的值,因此必须对null单独查找。如果未找到该元素则返回-1 。

public static

void main

(String[] args) {

ArrayList

list=new ArrayList();

list.add(1);

list.add(2);

list.add(null);

list.add(2);

list.add(3);

System.out.println

("null: "+list.indexOf(null));

System.out.println

("-------------------------");

System.out.println

("2: "+list.indexOf(2));

System.out.println

("-------------------------");

System.out.println

("4: "+list.indexOf(4));

}

//输出

/*

null: 2

-------------------------

2: 1

-------------------------

4: -1

*/

③lastIndexOf(Object o)方法

功能:查找某个元素在ArrayList中最后出现的位置。

public int lastIndexOf

(Object

o) {

if (o == null) {

//如果o为null从后往

前找到第一个为null的下标

for (int i = size-1; i >= 0; i--)

if (elementData[i]==null)

return i;

} else {

//从后往前找到第一个值为o的下标

for (int i = size-1; i >= 0; i--)

if (o.equals(elementData[i]))

return i;

}

return -1;

}

上面代码做几点说明:lastIndexOf(Object o)在ArrayList中从后往前找到第一个跟要查找值相同的元素的下标,因为是按值查找所以对于 null 要单独查找。如果未找到则返回-1;

④get(int index)方法

功能:返回ArrayList中指定下标为index的元素。

public E get(int

index) {

//检查index的值是否大于ArrayList的大小

rangeCheck(index);

//返回index下标的元素

return elementData(index);

}

E elementData(int index) {

return (E) elementData[index];

}

//这里值检查index >= size的情况,

因为index<0时会自动抛出异常,

所以并未检查index<0的情况。

private void rangeCheck

(int index) {

if (index >= size)

throw new IndexOutOfBoundsException

(outOfBoundsMsg(index));

}

对上面代码做几点说明:上面代码中只检查了index>=size的情况,在index< 0的情况下也会抛出异常,只是这个异常是由系统抛出的。index >=size要检查的原因是有可能数组的大小大于index,然而有效里面的元素< index这时不抛异常就会返回无效值。举个例子ArrayList的初始化大小为10,现在往里面放5个元素,如果index >=5时,应该要抛出异常,而不是返回 null。因为null 是可以主动放在ArrayList中的。

⑤set(int index, E element)方法

功能:将element放到ArrayList下标为index的位置,如果index< 0或index >=size 抛异常,set(int index, E element)只能覆盖ArrayList中原来的元素,返回值为被覆盖的元素。

//1

public E set(int index, E element) {

//检查index是否小于size,如果不是抛异常

rangeCheck(index);

E oldValue = elementData(index);

elementData[index] = element;

//覆盖ArrayList中index上的元素。

return oldValue;

//返回被覆盖的元素。

}

//2

private void rangeCheck

(int index) {

if (index >= size)

throw new IndexOutOfBoundsException

(outOfBoundsMsg(index));

}

⑥add(E e)方法

功能:往ArrayList中添加元素。

//1-----------------------

public boolean add(E e) {

ensureCapacityInternal(size + 1);

// 加入元素前检查数组的容量是否足够

elementData[size++] = e;

return true;

}

//2-----------------------

private void ensureCapacityInternal

(int minCapacity)

{

modCount++;

// 如果添加元素后大于

当前数组的长度,则进行扩容

if (minCapacity -

elementData.length > 0)

grow(minCapacity);

}

//3-----------------------

private void grow(int minCapacity) {

// overflow-conscious code

int oldCapacity = elementData.length;

//将数组的长度增加原来数组的一半。

int newCapacity = oldCapacity +

(oldCapacity >>

1);

if (newCapacity - minCapacity < 0)

newCapacity = minCapacity;

//如果扩充一半后仍然不够,则newCapacity= minCapacity;minCapacity实际元素的个数。

if (newCapacity - MAX_ARRAY_SIZE > 0)

newCapacity = hugeCapacity(minCapacity);

//数组最大位2^32

// minCapacity is usually close to size,

so this

is a win:

elementData = Arrays.copyOf

(elementData, newCapacity);

}

add方法比较复杂,涉及到扩充数组容量的问题。其中要弄清楚size和elementData.length的区别,size指的是数组中存放元素的个数,elementData.length表示数组的长度,当new一个ArrayList系统默认产生一个长度为10的elementData数组,elementData.length=10,但是由于elementData中还未放任何元素所有size=0。如果加入元素后数组大小不够会先进行扩容,每次扩容都将数组大小增大一半比如数组大小为10一次扩容后的大小为10+5=10;ArrayList的最大长度为 2^32 .

⑦add(int index, E element)方法

功能:往ArrayList指定index上添加元素,添加元素后ArrayList的大小增1。index及以后的元素都会向后移一位。 //1-------------------------

public void add

(int index, E element) {

rangeCheckForAdd(index);

//检查index的值是否

在0到size之间,可以为size。

ensureCapacityInternal(size + 1);

// 看elementData的长度是否足够,

不够扩容

//将elementData从index

开始后面的元素往后移一位。

System.arraycopy(elementData,

index, elementData,

index + 1,

size - index);

elementData[index] = element;

size++;

}

//2-------------------------

private void rangeCheckForAdd

(int index) {

if (index > size || index < 0)

throw new IndexOutOfBoundsException

(outOfBoundsMsg(index));

}

//3-------------------------

private void ensureCapacityInternal

(int minCapacity)

{

modCount++;

// overflow-conscious code

if (minCapacity - elementData.length > 0)

grow(minCapacity);

}

add(int index, E element)往指定index中加入元素,加入元素之前先检查数组的大小,如果小了在原来基础上增大一半,将ArrayList只能怪index及以后的元素往后移一位,将element放到index位置。

⑧remove(int index)方法

功能:删除ArrayList指定位置的元素。

public E remove(int

index) {

rangeCheck(index);

//如果index>=size抛出异常

modCount++;

E oldValue = elementData(index);

//获取删除元素的值

int numMoved = size - index - 1;

//将index后面所有的元素往前移一位。

if (numMoved > 0)

System.arraycopy(elementData,

index+1, elementData,

index,

numMoved);

elementData[--size] = null;

// Let gc do its work

//返回要删除的原数。

return oldValue;

}

⑨remove(Object o)方法

功能:删除ArrayList中值为o的元素

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;

}

java arraylist 实现原理_Java进阶--深入理解ArrayList实现原理相关推荐

  1. java 编程原理_Java网络编程 -- 网络编程基础原理

    Hello,今天记录下 Java网络编程 --> 网络编程基础原理. 一起学习,一起进步.继续沉淀,慢慢强大.希望这文章对您有帮助.若有写的不好的地方,欢迎评论给建议哈! 初写博客不久,我是杨展 ...

  2. Java设计流程执行器_Java进阶面试精选系列:SpringMVC+SpringBoot+Hibernate+Mybatis+设计模式...

    小编精心收集:为金三银四准备,以下面试题先过一遍,为即将到了的面试做好准备,也过一遍基础知识点. 一.Spring/Spring MVC 1.为什么要使用 spring? 2.解释一下什么是 aop? ...

  3. java同步方法完成案例_Java同步代码块和同步方法原理与应用案例详解

    本文实例讲述了java同步代码块和同步方法.分享给大家供大家参考,具体如下: 一 点睛 所谓原子性WOmoad:一段代码要么执行,要么不执行,不存在执行一部分被中断的情况.言外之意是这段代码就像原子一 ...

  4. java session原理_java web开发—session的工作原理总结

    session的工作原理总结 一.什么是session session是一次浏览器和服务器交互的会话,在jsp中,作为一个内置对象存在.我的理解,就是当用户打开网页时,程序会在浏览器中开辟一段空间来存 ...

  5. java static 变量共享_java中如何理解多个对象共享同一个静态成员变量?

    展开全部 要理解这个问题首先要知道一点,就是java的静态成62616964757a686964616fe59b9ee7ad9431333433643133员变量是有一个独立的存储空间的. 假设一个类 ...

  6. java 中适配器原理_Java经典设计模式中关于适配器模式原理以及用法详解

    这篇文章主要介绍了Java经典设计模式之适配器模式,简单说明了适配器模式的概念.原理,并结合实例形式分析了java适配器模式的用法与相关注意事项,需要的朋友可以参考下 本文实例讲述了Java经典设计模 ...

  7. java 迭代器的原理_Java集合框架迭代器Iterator实现原理解析

    使用循环遍历集合 普通for循环 for(int i=0;i<10;i++){} 增强for循环 for(String str:list){} 什么是迭代器Iterator Iterator是J ...

  8. java 同步块原理_Java同步代码块和同步方法原理与应用案例详解

    Java同步代码块和同步方法原理与应用案例详解 发布于 2020-8-7| 复制链接 摘记: 本文实例讲述了Java同步代码块和同步方法.分享给大家供大家参考,具体如下:一 点睛所谓原子性:一段代码要 ...

  9. 结构化分析与面向对象的区别_JAVA进阶 深入理解面向对象

    一.结构化程序设计与面向对象 1. 概述 早期的编程语言如:C.Basic.Pascal等都是结构化编程语言.结构化程序设计的核心思想就是程序的开发采用自上而下的设计(称为瀑布模式).对于大型的应用来 ...

最新文章

  1. 【leetcode75】Intersection of Two Arrays(数组的交集)
  2. Object-C 入门介绍
  3. Velocity语法使用总结
  4. 计算二叉树叶子节点的数目
  5. 虚拟机上安装完成redhat后无法上网和Xshell无法连接虚拟机的问题
  6. 2017年苹果公司开发者账号申请-公司邓白氏编码
  7. 2.18比赛(T2,T3留坑)
  8. 检验多重共线性matlab_异方差太难?检验通不过?横截面分析难题的十大暴击!...
  9. 80 后技术人的中年危机
  10. 公钥和私钥的作用和区别
  11. 20165309 《网络对抗技术》实验二:后门原理与实践
  12. JavaWeb——新闻管理系统(Jsp+Servlet)
  13. kindeditor 编辑器手机访问默认为HTML编辑
  14. android5.0电话录音,用Xpose完美实现电话录音,支持android 8.1.0
  15. 服务器显卡驱动重装系统,windows7旗舰版系统重装显卡驱动的方法
  16. gnuradio3.8.2的安装步骤
  17. 解决错误Establishing SSL connection without server‘s identity verification is not recommended.
  18. matlab怎么求解二元高次方程,高次二元方程求解
  19. Jquery引用在线CDN公共资源库
  20. 项目实训第一周第三篇

热门文章

  1. 如何同时安装Office2003和Office2007!
  2. 《AngularJS实战》——3.1 模板中的过滤器
  3. jQuery 的 serializeArray()、serialize() 方法
  4. 0x80070002错误一例
  5. 软件项目开发无成熟框架套路之成本代价
  6. ScribeFireBlog 发的一篇在Cnblogs的日志
  7. K-means聚类自定义距离计算
  8. 荣发护肤护甲增强配方 Hair, Skin and Nails Plus 100 tablets
  9. Oracle+jsp+Servlet的员工表的简单增删改查
  10. 使用 JMeter 进行压力测试