对于ArrayList集合可能大家并不陌生,但ArrayList集合的扩容机制大家是否了解呢?我们今天着重来看看
适用于什么场景?
检索比较多的场景
ArrayList特点
1、ArrayList集合底层采用了数据这种数据结构,是Object类型
2、ArrayList的默认初始容量为10,扩容因子为1.5
3、建议给定一个预估计的初始化容量,减少数组扩容的次数,这是ArrayList集合比较重要的优化策略.因为在在扩容的同时需要将原来数组中的数据复制到新数组里,但如果要插入大量数据时,赋值数组的形式效率很低,所以大多数情况下会使用带参构造函数,传入一个预估计容量,提前定义好容量。
4、ArrayList是非线程安全的
实战演练
import java.util.ArrayList; import java.util.List; public class ListTest { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("b");//第一个,索引下标0 list.add("d"); list.add("c"); list.add("a"); list.add("d"); //允许使用重复元素 System.out.println(list); //输出结果:[b, d, c, a, d] System.out.println(list.get(2)); //输出指定下标的元素,输出结果:c list.add(1,"f");//在指定索引下标位置添加元素 System.out.println(list); //输出结果:[b, f, d, c, a, d],原来下标为1和1之后的下标索引位置的元素自动向后移动 List<String> a = new ArrayList<String>(); a.add("123"); a.add("456"); list.addAll(2,a); //在指定索引下标的位置插入集合 System.out.println(list);//输出结果:[b, f, 123, 456, d, c, a, d] //获取指定元素在集合中第一次出现的索引下标 System.out.println(list.indexOf("d")); //输出结果:4 //获取指定元素在集合中最后一次出现的索引下标 System.out.println(list.lastIndexOf("d"));//输出结果:7 list.remove(2); //根据指定的索引下标移除元素 System.out.println(list); //输出结果:[b, f, 456, d, c, a, d] list.set(1,"ff"); //根据指定的索引下标修改元素 System.out.println(list); //输出结果:[b, ff, 456, d, c, a, d] //根据索引下标的起始位置截取一段元素形成一个新的集合,截取的时候,包含开始的索引不包含结束时的索引 List<String> sublist= list.subList(2,4); System.out.println(sublist);//输出结果:[456, d] System.out.println(list.size());//输出结果7 } }
import java.util.LinkedList; import java.util.List; public class ListTest { public static void main(String[] args){ List l1 = new LinkedList(); for(int i = 0;i<=5;i++){ l1.add("a"+i); } System.out.print(l1); l1.add(3,"a100"); System.out.println(l1); l1.set(6,"a200"); System.out.println(l1); System.out.print((String)l1.get(2)+" "); System.out.println(l1.indexOf("a3")); l1.remove(1); System.out.println(l1); } }
输出结果:
[a0,a1,a2,a3,a4,a5] [a0,a1,a2,a100,a3,a4,a5] [a0,a1,a2,a100,a3,a4,a200] a2 4 [a0,a2,a100,a3,a4,a200]
ArrayList扩容机制
ArrayList的使用前不需要像数组一样提前定义大小空间,容量是随着使用时自动增长的,那为什么在使用ArrayList的add方法添加元素的时候底层还需要判断集合的容量是否能够放下要添加的元素呢?又没有定义固定大小直接放进去不就好了吗?
add方法添加分为三步:
①、判断集合容量是否满足添加的元素
②、添加元素
③、集合长度+1
解答:
用户不需要提前定义大小,那是因为底层默认已经定义好了大小。其实是有一个边界值的,并不是无限增长的。使用时增加,是因为底层有扩展因子(扩容因子是1.5),当数量达到数组的百分之多少的时候就会扩容。ArrayList默认的初始大小是10
问题:大家可以思考思考为什么ArrayList底层扩容因子是1.5?为什么不是1.3、2.4……?
综上所述,ArrayList的特点如下
1、ArrayList集合底层采用了数据这种数据结构,是Object类型
2、ArrayList的默认初始容量为10,扩容因子为1.5
3、建议给定一个预估计的初始化容量,减少数组扩容的次数,这是ArrayList集合比较重要的优化策略.因为在在扩容的同时需要将原来数组中的数据复制到新数组里,但如果要插入大量数据时,赋值数组的形式效率很低,所以大多数情况下会使用带参构造函数,传入一个预估计容量,提前定义好容量。
4、ArrayList是非线程安全的