java 学习之四 ArrayList
来源:互联网 发布:网络音乐的主要格式是 编辑:程序博客网 时间:2024/06/11 15:19
ArrayList的主要特点
ArrayList比较适合顺序添加、随机访问的场景。
ArrayList允许元素数目为空
ArrayList允许重复数据
ArrayList是元素有序 (指的是插入和取出顺序相同)
ArrayList是非线程安全
添加元素
有这么一段代码:
public static void main(String[] args){ List<String> list = new ArrayList<String>(); list.add("000"); list.add("111");}看下底层会做什么,进入add方法的源码来看一下:
1 public boolean add(E e) {2 ensureCapacity(size + 1); // Increments modCount!!3 elementData[size++] = e;4 return true;5 }先不去管第2行的ensureCapacity方法,这个方法是扩容用的,底层实际上在调用add方法的时候只是给elementData的某个位置添加了一个数据而已,用一张图表示的话是这样的:
多说一句,我这么画图有一定的误导性。elementData中存储的应该是堆内存中元素的引用,而不是实际的元素,这么画给人一种感觉就是说elementData数组里面存放的就是实际的元素,这是不太严谨的。不过这么画主要是为了方便起见,只要知道这个问题就好了。
扩容
我们看一下,构造ArrayList的时候,默认的底层数组大小是10: (有的地方看到的写的是16)
public ArrayList() {this(10);}那么有一个问题来了,底层数组的大小不够了怎么办?答案就是扩容,这也就是为什么一直说ArrayList的底层是基于动态数组实现的原因,动态数组的意思就是指底层的数组大小并不是固定的,而是根据添加的元素大小进行一个判断,不够的话就动态扩容,扩容的代码就在ensureCapacity里面:
public void ensureCapacity(int minCapacity) { <span></span> modCount++;<span></span>int oldCapacity = elementData.length;<span></span>if (minCapacity > oldCapacity) { <span></span>Object oldData[] = elementData; <span></span>int newCapacity = (oldCapacity * 3)/2 + 1; <span></span>if (newCapacity < minCapacity) <span></span>newCapacity = minCapacity; <span></span>// minCapacity is usually close to size, so this is a win: <span></span>elementData = Arrays.copyOf(elementData, newCapacity);<span></span>}}
看到扩容的时候把元素组大小先乘以3,再除以2,最后加1。可能有些人要问为什么?我们可以想:
1、如果一次性扩容扩得太大,必然造成内存空间的浪费
2、如果一次性扩容扩得不够,那么下一次扩容的操作必然比较快地会到来,这会降低程序运行效率,要知道扩容还是比价耗费性能的一个操作
所以扩容扩多少,是JDK开发人员在时间、空间上做的一个权衡,提供出来的一个比较合理的数值。最后调用到的是Arrays的copyOf方法,将元素组里面的内容复制到新的数组里面去:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy;}
用一张图来表示就是这样的:
删除元素
接着我们看一下删除的操作。ArrayList支持两种删除方式:
1、按照下标删除
2、按照元素删除,这会删除ArrayList中与指定要删除的元素匹配的第一个元素
对于ArrayList来说,这两种删除的方法差不多,都是调用的下面一段代码:
int numMoved = size - index - 1;if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved);elementData[--size] = null; // Let gc do its work
其实做的事情就是两件:
1、把指定元素后面位置的所有元素,利用System.arraycopy方法整体向前移动一个位置
2、最后一个位置的元素指定为null,这样让gc可以去回收它
比方说有这么一段代码:
public static void main(String[] args){ List<String> list = new ArrayList<String>(); list.add("111"); list.add("222"); list.add("333"); list.add("444"); list.add("555"); list.add("666"); list.add("777"); list.add("888"); list.remove("333");}
0 0
- java 学习之四 ArrayList
- Java学习之ArrayList
- Java学习之ArrayList
- Java学习之ArrayList
- java学习 集合之arrayList
- Java集合学习之arrayList
- 深入学习Java之ArrayList
- java之LinkList、ListIterator、ArrayList学习
- Java学习之道:ArrayList的使用方法
- Java学习笔记之ArrayList基本用法
- Java集合之ArrayList源码概览学习
- java深入学习之ArrayList工作原理
- Java学习之ArrayList和LinkedList
- Java集合类学习之Arraylist、Linkedlist
- java学习之ArrayList容器类详解
- 共同学习Java源代码--数据结构--ArrayList类(四)
- (四)Java程序设计之数组和ArrayList类
- Java Thread学习之四
- FMDB简单使用(附github源代码)
- 第十二周实践项目3-数组类运算的实现
- 计算机程序的构造和解释 练习1.9
- 第六次上机作业
- 【Android】导入第三方库时,关于so文件的一些思考
- java 学习之四 ArrayList
- 几种基础的算法学习 (php)
- 第十周上机时间项目——项目1—点圆圆柱类族的设计
- JAVA字符串与字符编码处理的终极解决
- Windows远程调试Linux上的C++程序:Eclipse+MingW+Samba+GDBserver
- c++实验六 项目3
- shell字符处理命令,通配符,正则表达式
- ARM平台移植libcurl curl-7.49.0
- 第十一周上机实践项目 项目3-警察和厨师(1)