Java集合框架使用注意事项
2008-11-29 13:32
218 查看
List的有用实现
1.ArrayList
2.LinkedList
3.Vector
4.Stack
讨论1:底层机制(牵扯到的数据结构的知识请读者自行复习)
ArrayList与Vector都是基于数组实现的,这就说明ArrayList与Vector适合做遍历而不适合做频繁的插入和删除。
LinkedList是基于链表实现的,所以它生来就是为了频繁插入与删除对象。
讨论2:特殊功能
Stack是一个后进先出(LIFO)对象堆栈,而LinkedList除可以被用作堆栈外,还可以被用作队列或双端队列。
不同的是Stack继承自Vector,也就是说它也是基于数组实现的。
讨论3:内存占用
基于数组实现的List,在动态扩展时会产生新的数组,然后把旧数组里的内容复制到新数组里,这会产生大量的不再被使用的对象引用变量等待系统回收。而基于链表实现的List就不会有这种问题。
讨论4:同步问题
Vector与Stack生来就是同步的,而ArrayList与LinkedList需要使用Collections.synchronizedList(List list)方法来转换成同步List.从它们的对象上返回的迭代器是快速失败的,也就是说在使用迭代器进行迭代的时候,必须使用迭代器本身的remove、add、set方法来添加或更改List元素,如果在迭代的同时,在其他线程中从结构上修改了List(结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改),快速失败迭代器会尽最大努力抛出ConcurrentModificationException.
讨论5:使用策略
如果数据被从数据源提取,数据量不确定,该数据一经被提取后就几乎不会再添加或删除,那么应该建立一个LinkedList来保存从数据源中取出的数据,然后将该LinkedList转换成ArrayList来优化遍历操作。反过来,数据量确定的数据从数据源取出可以先建立一个ArrayList来保存,根据需要如需频繁增删,就转换为LinkedList,如频繁遍历就不需转换。
转换的方法就是使用对应的List类来封装目标List对象。如
ArrayList al = new ArrayList();
LinkedList ll = new LinkedList(al);
同理反过来也可以
LinkedList ll = new LinkedList();
ArrayList al = new ArrayList(ll);
讨论6:toArray()方法
基于数组实现的List会直接返回一个底层数组的拷贝(使用了System.arraycopy方法),Examda提示: 基于链表实现的List会新生成一个数组。
讨论7:不可修改
通过使用Collections.unmodifiableList(List list)来生成一个不可修改的List,试图修改返回的列表,不管是直接修改还是通过其迭代器进行修改,都将导致抛出UnsupportedOperationException.
讨论8:遍历器
请尽量使用Iterator,Enumeration已不被鼓励使用。
最后,请参考java.util.Collections类,该类提供了很多有用的操纵集合对象的方法。
Map接口常用的实现类有:
1.HashMap
2.Hashtable
3.TreeMap
4.LinkedHashMap
讨论1:底层机制
HashMap与Hashtable基于数组实现,TreeMap基于树型结构,底层存储结构是典型的链表结构。LinkedHashMap继承自HashMap,所以也是基于数组实现的。
讨论2:继承关系
HashMap与TreeMap继承自AbstractMap,Hashtable继承自Dictionary,LinkedHashMap继承自HashMap.
讨论3:同步关系
Hashtable是同步的,而HashMap与TreeMap以及LinkedHashMap不是同步的,可以使用Collections中提供的方法转换为同步的。
讨论4:迭代器
迭代器都是快速失败的(注:参考本系列第一篇List篇)
讨论5:不可修改
通过使用Collections.unmodifiableMap(Map map)来转换。
1.ArrayList
2.LinkedList
3.Vector
4.Stack
讨论1:底层机制(牵扯到的数据结构的知识请读者自行复习)
ArrayList与Vector都是基于数组实现的,这就说明ArrayList与Vector适合做遍历而不适合做频繁的插入和删除。
LinkedList是基于链表实现的,所以它生来就是为了频繁插入与删除对象。
讨论2:特殊功能
Stack是一个后进先出(LIFO)对象堆栈,而LinkedList除可以被用作堆栈外,还可以被用作队列或双端队列。
不同的是Stack继承自Vector,也就是说它也是基于数组实现的。
讨论3:内存占用
基于数组实现的List,在动态扩展时会产生新的数组,然后把旧数组里的内容复制到新数组里,这会产生大量的不再被使用的对象引用变量等待系统回收。而基于链表实现的List就不会有这种问题。
讨论4:同步问题
Vector与Stack生来就是同步的,而ArrayList与LinkedList需要使用Collections.synchronizedList(List list)方法来转换成同步List.从它们的对象上返回的迭代器是快速失败的,也就是说在使用迭代器进行迭代的时候,必须使用迭代器本身的remove、add、set方法来添加或更改List元素,如果在迭代的同时,在其他线程中从结构上修改了List(结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改),快速失败迭代器会尽最大努力抛出ConcurrentModificationException.
讨论5:使用策略
如果数据被从数据源提取,数据量不确定,该数据一经被提取后就几乎不会再添加或删除,那么应该建立一个LinkedList来保存从数据源中取出的数据,然后将该LinkedList转换成ArrayList来优化遍历操作。反过来,数据量确定的数据从数据源取出可以先建立一个ArrayList来保存,根据需要如需频繁增删,就转换为LinkedList,如频繁遍历就不需转换。
转换的方法就是使用对应的List类来封装目标List对象。如
ArrayList al = new ArrayList();
LinkedList ll = new LinkedList(al);
同理反过来也可以
LinkedList ll = new LinkedList();
ArrayList al = new ArrayList(ll);
讨论6:toArray()方法
基于数组实现的List会直接返回一个底层数组的拷贝(使用了System.arraycopy方法),Examda提示: 基于链表实现的List会新生成一个数组。
讨论7:不可修改
通过使用Collections.unmodifiableList(List list)来生成一个不可修改的List,试图修改返回的列表,不管是直接修改还是通过其迭代器进行修改,都将导致抛出UnsupportedOperationException.
讨论8:遍历器
请尽量使用Iterator,Enumeration已不被鼓励使用。
最后,请参考java.util.Collections类,该类提供了很多有用的操纵集合对象的方法。
Map接口常用的实现类有:
1.HashMap
2.Hashtable
3.TreeMap
4.LinkedHashMap
讨论1:底层机制
HashMap与Hashtable基于数组实现,TreeMap基于树型结构,底层存储结构是典型的链表结构。LinkedHashMap继承自HashMap,所以也是基于数组实现的。
讨论2:继承关系
HashMap与TreeMap继承自AbstractMap,Hashtable继承自Dictionary,LinkedHashMap继承自HashMap.
讨论3:同步关系
Hashtable是同步的,而HashMap与TreeMap以及LinkedHashMap不是同步的,可以使用Collections中提供的方法转换为同步的。
讨论4:迭代器
迭代器都是快速失败的(注:参考本系列第一篇List篇)
讨论5:不可修改
通过使用Collections.unmodifiableMap(Map map)来转换。
相关文章推荐
- Java集合框架使用注意事项(一, List)
- 为什么用group by 以及使用的方法和注意事项
- 缓存 使用注意事项 淘汰策略
- PCB的使用注意事项
- coordinatorLayout使用详解及注意事项,看完这篇完全可以开发5.0的高级特效了
- java集合框架中List的定义以及一些注意事项
- startActivityForResult 使用注意事项
- PHY使用MII和RMII与SAM9260链接时需要注意的事项
- iPhone SDK中多线程的使用方法以及注意事项 转载
- js闭包避免内存泄漏 减少内存使用 避免对象无法回收注意事项
- 彻底学会使用epoll(五)—— ET模式下的注意事项
- Delphi7中接口使用的注意事项与原因
- 【ZooKeeper Notes 15】Watcher使用的注意事项
- ECSHOP session 的使用 注意事项 ,ecshop 批发 代码模式切换,普通会员特殊会员切换
- 关于Runtime Permissions的学习以及使用的一些注意事项
- 关于libjpeg或libjpeg-turbo使用中的一个注意事项
- 苹果微信分身版使用教程与注意事项
- 使用Hint时的注意事项
- Android中关于线程使用的几点注意事项
- python引用下标或者使用range函数时时注意事项