ArrayList 、LinkList、List 区别 & 迭代器iterator的使用 & HashMap、Hashtable、LinkedHashMap、TreeMap
一、几个List类型
1.大学数据结构中ArrayList是实现了基于动态数组的数据结构,LinkList基于链表的数据结构。
2.对于随机访问get和set,ArrayList优于LinkList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinkList比较占优势,因为ArrayList要移动数据。
从上面三点可以看出:
ArrayList和LinkList是两个集合类,用于存储一系列的对象引用(references)。例如我们可以用ArrayList来存储一系列的String或者Integer。
而,List继承自Collection接口。List是一种有序集合,List中的元素可以根据索引(顺序号:元素在集合中处于的位置信息)进行取得/删除/插入操作。
总结如下:
List是一个接口,ArrayList、LinkList继承与这个接口并实现了它.
用的时候,可以这么用: List<String> list = new ArrayList<String 等同于 ArrayList<String> list=new ArrayList<String>
补充一点:
这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与hashset没有任何关系,但为了说清楚ArrayList与Vector的功能,我们使用对比方式,更有利于说明问题)。
接着才说ArrayList与Vector的区别,这主要包括两个方面:. (1)同步性:
Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。
备注:对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不安全的。(2)数据增长:
ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。
总结:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。
二、迭代器
迭代器一般和泛型数组ArrayList,泛型链表LinkList配合使用,达到顺序遍历的效果.
先来看看下面两段代码:解释写在代码注释里了
[java]
private ArrayList<String> getChecked() { /** * ArrayList<PhotoItem>用来存放图片信息 */ private ArrayList<PhotoItem> mPhotolist = null; /** * new一个ArrayList<String>,用来存放文件的地址path */ ArrayList<String> list = new ArrayList<String>(); /** * 给mPhotolist加上迭代器,对它进行顺序遍历操作,这里是关键!it只是一个迭代器对象 */ Iterator<PhotoItem> it = mPhotolist.iterator(); while (it.hasNext()) { /** * 把遍历得到的PhotoItem类型对象赋值给PhotoItem类型对象temp */ PhotoItem temp = it.next(); if (temp.isChecked) { String path = getRealPath(temp.ImageID); if (path != null) { list.add(path); } } } return list; }
第二段代码其实和第一段代码所实现的功能是一样的,大家可以参考一下,作个比较! [java]
@Override protected void onResume() { List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>(); Iterator<Mp3Info> iterator = mp3Infos.iterator(); while (iterator.hasNext()) //for (Iterator iterator = mp3Infos.iterator(); iterator.hasNext();) { Mp3Info mp3Info = iterator.next(); HashMap<String, String> map = new HashMap<String, String>(); map.put("mp3_name", mp3Info.getMp3Name()); map.put("mp3_size", mp3Info.getMp3Size()); list.add(map); } }
三、HashMap、Hashtable、LinkedHashMap、TreeMap
Map有四个实现类,分别是HashMap Hashtable LinkedHashMap 和 TreeMap.
Map主要用于存储健值对,根据键得到值,因此不允许键重复(重复了覆盖了),但允许值重复。
Hashmap 是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。 HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。
Hashtable与 HashMap类似,它继承自Dictionary类,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了 Hashtable在写入时会比较慢。
LinkedHashMap 是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比 LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。
TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。
一般情况下,我们用的最多的是HashMap,在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。如果需要输出的顺序和输入的相同,那么用LinkedHashMap 可以实现,它还可以按读取顺序来排列.