Java 集合框架(二)—— ArrayList
二、数组列表 —— ArrayList

1、构造方法
ArrayList 是 Java 中的动态数组,底层实现就是对象数组,只不过数组的容量会根据情况来改变。
它有个带 int 类型参数的构造方法,根据传入的参数,扩展初始化的数组容量,这个方法是推荐使用的,因为如果预先知道数组的容量,可以设置好初始值,而不用等每次容量不够而扩容,减少 Arrays.copyOf 的次数:

它的很多方法的实现都是依靠 Arrays 这个工具类完成的,足以体现它与数组之间的密切关系。
比如有个带 Collection 类型的构造方法,实现如下:

2、常用方法
1) trimToSize 方法
Trims the capacity of this ArrayList instance to be the list's current size.
An application can use this operation to minimize the storage of an ArrayList instance.
该方法可以去掉 ArrayList 占用的多余的空间或内存,因为 ArrayList 每次扩容后总会有所剩余,如果数组很大,占用的多余的空间会比较大,内存不够时可以使用此方法。
2)ensureCapacity 方法
public void ensureCapacity(int minCapacity)
Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.
除了在初始化 ArrayList 的时候可以事先定义一个给定的容量之外,还可以用此方法提高 ArrayList 的初始化速度。看下面的例子:
public static void main(String[] args) {
int n = 100000;
String str = "hello google";
// 没有调用 ensureCapacity() 方法初始化 ArrayList 对象
ArrayList<String> list = new ArrayList<>();
long startTime = System.currentTimeMillis();
for (int i = 0; i <= n; i++) {
list.add(str);
}
long endTime = System.currentTimeMillis();
System.out.println("time: " + (endTime - startTime) + " ms");
// 调用 ensureCapacity() 方法初始化 ArrayList 对象
list = new ArrayList<>();
startTime = System.currentTimeMillis();
list.ensureCapacity(n);
for (int i = 0; i < n; i++) {
list.add(str);
}
endTime = System.currentTimeMillis();
System.out.println("time: " + (endTime - startTime) + " ms");
}
结果为:

3)isEmpty 方法
注意此方法是判断是否为空,不是是否为 null
public boolean isEmpty() {
return size == 0;
}
4)indexOf 、lastIndexOf 和 contain 方法
indexOf 方法返回 list 中首次出现给定对象的索引值(从 0 开始),如果不存在则返回 -1。
lastIndexOf 方法返回 list 中最后一次出现给定对象的索引值(从 size - 1 开始),如果不存在则返回 -1。
contain 方法 参数为 Object o,判断 list 中是否包含给定的对象,存在则返回 true,源码如下:

5)add,get 和 set 方法
三个很简单的方法,区别在于:add 方法是数组长度 +1,将给定对象放在最后的位置,set 方法是替换指定索引位置的元素,get 方法则是获取指定索引位置的元素。
6)remove 方法
删除指定索引位置的元素或者指定元素,不推荐使用,对数组操作比较复杂,如果你使用了此方法,说明你应该考虑用 LinkedList 了。
3、最佳使用建议
1)ArrayList 是 Array 的复杂版本
ArrayList 内部封装了一个 Object 类型的数组,从一般的意义来说,它和数组没有本质的差别,甚至于 ArrayList 的许多方法,如 Index、IndexOf、Contains、Sort 等都是在内部数组的基础上直接调用 Array 的对应方法。
2)内部的 Object 类型的影响
对于一般引用类型来说,这部分的影响不大,但是对于值类型,往 ArrayList 里面添加和修改元素,都会引起装箱和拆箱操作,频繁的操作可能会影响一部分效率。
3)数组扩容
这是对 ArrayList 效率影响比较大的一个因素。
每当执行 Add、AddRange、Insert、InsertRange 等添加元素的方法,都会检查内部数组的容量是否不够了,如果是,它就会以当前容量的两倍来重新构建一个数组,将旧元素 Copy 到新数组中,然后丢弃旧数组,在这个临界点的扩容操作,应该来说是比较影响效率的。
例 1:比如,一个可能有 200 个元素的数据动态添加到一个以默认 16 个元素大小创建的 ArrayList 中,将会经过:
16*2*2*2*2 = 256
四次的扩容才会满足最终的要求,那么如果一开始就以 ArrayList list = new ArrayList(210) 的方式创建 ArrayList,不仅会减少 4 次数组创建和 Copy 的操作,还会减少内存使用。
例 2:预计有 30 个元素而创建了一个 ArrayList:
ArrayList List = new ArrayList(30);
在执行过程中,加入了 31 个元素,那么数组会扩充到 60 个元素的大小,而这时候不会有新的元素再增加进来,而且有没有调用 TrimSize 方法,那么就有 1 次扩容的操作,并且浪费了 29 个元素大小的空间。如果这时候,用 ArrayList list = new ArrayList(40) 那么一切都解决了。
所以说,正确的预估可能的元素,并且在适当的时候调用 TrimSize 方法是提高 ArrayList 使用效率的重要途径。
特别感谢:
2、《Thinking In Java》
3、《Core Java Volume I》
Java 集合框架(二)—— ArrayList的更多相关文章
- Java集合框架之ArrayList浅析
Java集合框架之ArrayList浅析 一.ArrayList综述: 位于java.util包下的ArrayList是java集合框架的重要成员,它就是传说中的动态数组,用MSDN中的说法,就是Ar ...
- (Set, Map, Collections工具类)JAVA集合框架二
Java集合框架部分细节总结二 Set 实现类:HashSet,TreeSet HashSet 基于HashCode计算元素存放位置,当计算得出哈希码相同时,会调用equals判断是否相同,相同则拒绝 ...
- java 集合框架(二)Iterable接口
Iterable接口是java 集合框架的顶级接口,实现此接口使集合对象可以通过迭代器遍历自身元素,我们可以看下它的成员方法 修饰符和返回值 方法名 描述 Iterator<T> iter ...
- Java——集合框架之ArrayList,LinkedList,迭代器Iterator
概述--集合框架 Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(Java Collection ...
- Java集合框架(二)
Set Set:无序,不可以重复元素. |--------HashSet:数据结构是哈希表. 线程是非同步的.保证元素唯一性的原理是:判断元素的hashCode值是否相同,如果相同,还会继续判断元素的 ...
- java集合框架03——ArrayList和源码分析
最近忙着替公司招人好久没写了,荒废了不好意思. 上一章学习了Collection的架构,并阅读了部分源码,这一章开始,我们将对Collection的具体实现进行详细学习.首先学习List.而Array ...
- Java集合框架(一)-ArrayList
大佬理解->Java集合之ArrayList 1.ArrayList的特点 存放的元素有序 元素不唯一(可以重复) 随机访问快 插入删除元素慢 非线程安全 2.底层实现 底层初始化,使用一个Ob ...
- java集合框架05——ArrayList和LinkedList的区别
前面已经学习完了List部分的源码,主要是ArrayList和LinkedList两部分内容,这一节主要总结下List部分的内容. List概括 先来回顾一下List在Collection中的的框架图 ...
- 深入理解java集合框架之---------Arraylist集合 -----添加方法
Arraylist集合 -----添加方法 1.add(E e) 向集合中添加元素 /** * 检查数组容量是否够用 * @param minCapacity */ public void ensur ...
- java集合框架之ArrayList
参考http://how2j.cn/k/collection/collection-arraylist/363.html 使用数组的局限性 一个长度是10的数据:Hero[] heroArr=new ...
随机推荐
- 【python】基础入门
1.正则表达式 import re sql="aaa$1bbbbccccc$2sdfsd gps_install_note_id =$3;" regexp=r'\$\d+' # 编 ...
- .net core 与ELK(4)后台运行els可视化工具和Kibana
which nohup .bash_profile中并source加载 如果没有就安装吧 yum provides */nohup nohup npm run start & nohup ./ ...
- C# DataTable导出EXCEL后身份证、银行卡号等长数字信息显示乱码解决
在DataTable导出EXCEL后发现有些格式显示有问题,比如身份证.银行卡号等大于11位的数字显示为科学计数法.13681-1等 带中划线的两段数字显示为日期格式等. 处理方法如下: public ...
- 移植Max中的控制器到Unity - 前言
一切源自于一个ppt http://pan.baidu.com/s/1kT8x2V9 看到这个ppt之前,其实自己也想过将Max当中的一些约束移植到游戏中,一方面是那时候能力不足,另一方面还是自己不那 ...
- 《JavaScript模式》一书中提到的一些坑
1. 应当用数组字面量来创建数组,而不是用new Array() //反模式 var a = new Array('itsy', 'bitsy', 'spider'); //用字面量 var a = ...
- Day 4 list 列表的使用方法
https://www.cnblogs.com/fanison/p/7123532.html s="abcdefg"print("s[3]:",s[3])pr ...
- BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)
5395: [Ynoi2016]谁的梦 Time Limit: 80 Sec Memory Limit: 128 MBSubmit: 22 Solved: 7[Submit][Status][Di ...
- UIVisualEffectView(高斯模糊效果)
///高斯模糊. UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)]; tempView. ...
- libevent源码剖析
libevent是一个使用C语言编写的,轻量级的开源高性能网络库,使用者很多,研究者也很多.由于代码简洁,设计思想简明巧妙,因此很适合用来学习,提升自己C语言的能力. libevent有这样显著地几个 ...
- Cassandra的数据模型
Cassandra的数据模型可以理解为嵌套的Map,在Cassandra中数据类型主要有四种:Column,SuperColumn,ColumnFamily,Keyspace.下面分别介绍这几种类型. ...