Java的容器类其实就是集合类,只是为了不与Collection接口混淆,国内基本翻译为容器类。
容器类分为两种:独立元素序列的Collection和键值对的Map.
Collection主要有如下几种:
- List:按插入顺序保存元素;
- ArrayList:擅长于随机访问元素,但是在List的中间插入和移除元素较慢;
- LinkedList:插入删除代价较低,特性集比ArrayList大,但随机访问相对比较慢;
- Set:不重复保存元素;
- HashSet:提供最快查找,使用了散列函数,顺序是杂乱的;
- TreeSet:按照比较结果的升序保存对象,保留了HashSet的查询速度;
- LinkedHashSet:按照被添加的顺序保存对象,使用了散列函数,同时保留了HashSet的查询速度;
- Queue:按排队规则顺序保存元素;
Map:一组成对的“键值对”对象,允许键来查找值,有如下几种:
- HashMap:提供最快的查找,没有明显顺序保存对象;
- TreeMap:按照比较结果的升序保存键,保留了HashMap的查询速度;
- LinkedHashMap:按照插入的顺序保存键,保留了HashMap的查询速度;
示例
package net.oseye; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; public class RunMain { public static void main(String[] args) { int total=1000000; List<Integer> arrayList=new ArrayList<Integer>(); List<Integer> linkedList=new LinkedList<Integer>(); long start=System.currentTimeMillis(); for(int i=0;i<total;i++){ arrayList.add(i); } long end=System.currentTimeMillis(); System.out.println("ArrayList插入数据时间:"+(end-start)); start=System.currentTimeMillis(); for(int i=0;i<total;i++){ linkedList.add(i); } end=System.currentTimeMillis(); System.out.println("LinkedList插入数据时间:"+(end-start)); start=System.currentTimeMillis(); Iterator<Integer> itArrayList=arrayList.iterator(); while(itArrayList.hasNext()){ itArrayList.next(); } end=System.currentTimeMillis(); System.out.println("ArrayList顺序访问时间:"+(end-start)); start=System.currentTimeMillis(); Iterator<Integer> itLinkedList=linkedList.iterator(); while(itLinkedList.hasNext()){ itLinkedList.next(); } end=System.currentTimeMillis(); System.out.println("LinkedList顺序访问时间:"+(end-start)); start=System.currentTimeMillis(); for(int i=0;i<total;i++){ arrayList.get(i); } end=System.currentTimeMillis(); System.out.println("ArrayList随机访问时间:"+(end-start)); start=System.currentTimeMillis(); for(int i=0;i<total;i++){ linkedList.get(i); } end=System.currentTimeMillis(); System.out.println("LinkedList随机访问时间:"+(end-start)); } }
输出
ArrayList插入数据时间:219
LinkedList插入数据时间:266
ArrayList顺序访问时间:15
LinkedList顺序访问时间:16
ArrayList随机访问时间:16
输出结果少了一条“随机访问时间”,因为实在太慢了,我等了20+分钟一直没出现结果,就先放弃了。
而插入时间ArraryList反而快,估计是因为都是在尾部添加所致,如果随机插入就可以看出结果了:
package net.oseye; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public class RunMain { public static void main(String[] args) { int total=100000; List<Integer> arrayList=new ArrayList<Integer>(); List<Integer> linkedList=new LinkedList<Integer>(); for(int i=0;i<1000;i++){ arrayList.add(i); } for(int i=0;i<1000;i++){ linkedList.add(i); } long start=System.currentTimeMillis(); for(int i=0;i<total;i++){ arrayList.add(800,i); } long end=System.currentTimeMillis(); System.out.println("ArrayList插入数据时间:"+(end-start)); start=System.currentTimeMillis(); for(int i=0;i<total;i++){ linkedList.add(800,i); } end=System.currentTimeMillis(); System.out.println("LinkedList插入数据时间:"+(end-start)); } }
输出
ArrayList插入数据时间:3391
LinkedList插入数据时间:203
PS:我这里一直存在一个疑问:我使用迭代器遍历,是否就是传说中的顺序访问呢?(待解决)