【Java集合类】ArrayList详解 (JDK7)
相信对于使用过Java的人来说,ArrayList这个类大家一定不会陌生。
数据结构课上讲过,
Array是数组,它能根据下标直接找到相应的地址,所以索引速度很快,但是唯一的缺点是不能动态改变数组的长度,复杂度O(1)。
而List就是链表,它搜索相应地址都只能从链表头部一个一个找下去,直至找到对应的地址才停止,相比于数组来说,搜索速度肯定是慢的,但是有点是能动态的增删节点,复杂度O(n)。
而Java中这个ArrayList到底是什么东西呢?
先上代码,我们平时使用ArrayList一般这样使用:
public class ArrayListTest {
public static void main( String[] args ) {
List<Integer> list = new ArrayList<Integer>();
list.add( );
list.add( );
list.get( );
list.remove( );
}
}
好,现在来解释每一步操作jdk做的事:
先看new ArrayList<>()初始化,
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < )
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this();
}
很明显,如果初始化不指定capacity的话,默认初始化数组大小就是10。
其实细心发现,在重载的构造函数中,
this.elementData = new Object[initialCapacity];
这行代码暴露了ArrayList的本质,其实就是一个数组。
OK,现在我们拥有了一个长度为10的数组对象,现在我们执行add操作,看jdk操作
public boolean add(E e) {
ensureCapacityInternal(size + ); // Increments modCount!!
elementData[size++] = e;
return true;
}
1.首先,暂且不理会ensureCapacityInternal()方法做的事,直接看【elementData[size++]=e】这行代码,显然地,是在elementData对象的size索引位置指向新元素,问题来了,万一size已经超出了当前数组的最大长度(假设是在第11个位置放置新元素),怎么办?
这里就要看ensureCapacityInternal方法了。
private void ensureCapacityInternal(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
这里可以很清楚地看出,
minCapacity - elementData.length > 0
这行代码检查了新增的元素位置是否超出了当前数组对象的最大长度,基于上面的假设,此判断是成立的,所以需要继续往下看,看grow()方法。
private void grow(int minCapacity) {
// overflow-conscious code
int 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);
}
看第二行代码,newCapacity = oldCapacity + oldCapacity / 2;
就是说每次当发现当前数组长度不足时,每次增加的步长是【0.5倍的当前长度】。
Ps.注意这里有一个坑,假如增加长度后超出了Max_ARRAY_SIZE(jdk定义为maxIntValue-8),直接返回MaxIntValue。 最后就是调用Arrays.copyOf方法了,里面主要调用的是System.arrayCopy方法,是一个JNI调用,有兴趣的同学可以去JDk官网看底层的实现,这里就不多累赘了。 --------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------- 接着来看看remove方法。
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; // Let gc do its work
return oldValue;
}
remove就比较简单了,它的原理就是找到要删除的下标,假设数组[1,2,3,4,5]你要删除3,jdk的做法就是把[1,2]和[4,5]数组复制到原数组,形成新数组[1,2,4,5,5],
然后执行elementData[--Size]防止内存泄露,完毕~
总结:
ArrayList就是一个通过申请新内存来扩容的数组!
【Java集合类】ArrayList详解 (JDK7)的更多相关文章
- Java集合类的详解与应用
Java集合类的详解与应用 集合简介: 1.定义:可以同时存储不同类型的数据 他的存储空间会随着数据的增大而增大 2.缺点:只能存储引用数据类型 3.优点:更加合理的利用空间,封装了更多的方法,用起来 ...
- java集合类,详解
集合详解 1.1HashSet HashSet是Set接口的一个子类,主要的特点是:里面不能存放重复元素,而且采用散列的存储方法,所以没有顺序.这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致 ...
- Java.util.ArrayList详解
java.util.ArrayList就是传说中的动态数组. 继承了关系,有此可看出ArrayList与list的collection的关系 public class ArrayList<E&g ...
- Java 8 ArrayList 详解
GitHub Page: http://blog.cloudli.top/posts/Java-ArrayList/ ArrayList 继承于 AbstractList ,实现了 List.Rand ...
- java集合类图详解
- [转载]Java迭代器(iterator详解以及和for循环的区别)
Java迭代器(iterator详解以及和for循环的区别) 觉得有用的话,欢迎一起讨论相互学习~[Follow] 转载自 https://blog.csdn.net/Jae_Wang/article ...
- ArrayList详解-源码分析
ArrayList详解-源码分析 1. 概述 在平时的开发中,用到最多的集合应该就是ArrayList了,本篇文章将结合源代码来学习ArrayList. ArrayList是基于数组实现的集合列表 支 ...
- 转:Java HashMap实现详解
Java HashMap实现详解 转:http://beyond99.blog.51cto.com/1469451/429789 1. HashMap概述: HashMap是基于哈希表的M ...
- java集合框架详解
java集合框架详解 一.Collection和Collections直接的区别 Collection是在java.util包下面的接口,是集合框架层次的父接口.常用的继承该接口的有list和set. ...
随机推荐
- underscore 1.7.0 api
它是这个问题的答案:“如果我在一个空白的HTML页面前坐下, 并希望立即开始工作, 我需要什么?“ http://www.css88.com/doc/underscore/#
- JSP 初始化参数
JSP 初始化参数: tomcat启动的时候就会执行那个函数: xml: <?xml version="1.0" encoding="UTF-8"?> ...
- Bootstrap入门(二十)组件14:警告框
Bootstrap入门(二十)组件14:警告框 警告框组件通过提供一些灵活的预定义消息,为常见的用户动作提供反馈消息,提示.通知或者警示,可以迅速吸引注意力. 1.情景警告框 2.可关闭的警告框 3. ...
- css3 小图标提示特效
最近的计划,就是每天来几个特效,当然这里有限制,在什么候选区只能放一个,还每天有限制发布的,哎, 啊 终于写完了,看到一个挺好玩的东西,想到能不能用网页的特效做出来,试试呗!不过,一想肯东有很多的 相 ...
- [CSS3] 学习笔记-CSS动画特效
在CSS3中,出现了很多出彩的效果,例如2D.3D以及过度.动画和多列等.这些效果为页面设计添加了很多的可选设计. 1.2D.3D转换 转换,是使元素改变尺寸.形状.位置的一种效果:通过CSS3转换, ...
- [CSS3] 学习笔记-CSS定位
页面的设计需要通过摆放不同的模块在不同的位置,这个时候需要使用到定位和浮动的知识点,CSS3定位功能是很强大的,利用它你可以做出各种各样的网络布局. 1.CSS定位 1)定位机制 普通流:元素按照其在 ...
- 蓝桥网试题 java 入门训练 Fibonacci数列
---------------------------------------------------------------------------------------------------- ...
- Vue.js 系列教程 ①
原文:intro-to-vue-1-rendering-directives-events 译者:nzbin 如果要我用一句话描述使用 Vue 的经历,我可能会说“它如此合乎常理”或者“它提供给我需要 ...
- display的none与block(判断登录界面的账号密码是否为空)
判断登录界面的账号密码是否为空的时候又不想用alert显示就需要用display来隐藏alert啦(在设置时切忌要将隐藏的内容写在账号和密码的div中,否则会根据屏幕的分辨率不同而有所变化,这是本人教 ...
- Ubuntu16.04+Theano环境
安装Anaconda: 官网下载Anaconda 切换到下载目录 cd ~/下载/ 用bash运行下载好的.sh文件 bash Anaconda2--Linux-x86_64.sh 进入欢迎界面 We ...