对于JDK中常用包实现形式的整理,整理自《分布式Java应用》一书
1、集合包
Java中最常用的有Collection和Map两个接口的实现类,其中Map用于存放Key-Value形式的键值对。
Collection中分为List和Set两种类型的接口:List支持放入重复的对象,Set不支持。
List的实现类由ArrayList、LinkedList、Vector、Stack。
Set接口常用的实现类为HashSet、TreeSet。
遍历Collection中的对象可以用iterator方法获取迭代器。
1.1 ArrayList的实现方式
在ArrayList的创建方法中最关键的是实例化了一个Object的数组,数组大小为initialCapacity的值。
调用add(E)方法时,首先基于ArrayList中已有的元素数量加1,存入一个名为minCapacity的变量,然后比较此值和Object数组的大小,如果此值大于Object数组值,则先将当前的Object数组赋给一个数组对象,并确定新的数组容量,最后将数组的末尾赋值为传入的对象。
调用add(int,E)时,额外的操作是需要把目前index和其后的数据都往后移动一位。
remove(E)方法中调用fastRemove方法将index后的对象往前赋值一位并将数组的最后一个元素的值设置为null,即释放了对此对象的引用。
iterator()方法:每次调用iterator方法时,都会创建一个新的Itr的实例。调用next方法时,首先比较在创建此Iterator时获取的modCount与目前的modCount,如果这两个modCount不相等,则说明在获取next元素时,发生了对于集合大小产生影响的如新增删除的动作。
ArrayList是非线程安全的。
1.2 LinkedList实现方式
add(E)方法:LinkedList的add方法不用向ArrayList那样,要考虑扩容及赋值数组的问题,但它每增加一个元素,都要创建一个新的对象,并要修改相邻的两个元素的属性。
iterator():
调用next方法时,内部调用get方法实现,如果在遍历过程中,LinkedList中的元素增加或删除,则会跑出异常。
LinkedList是非线程安全的。
1.3 Vector
Vector和ArrayList一样,也是基于Object数组的方式来实现的。
add(E)方法:Vector中的add方法是加了synchronized关键字的,因此此方法时线程安全的。除此之外Vector的扩容策略与ArrayList不同。
Vector是基于Synchronized实现的线程安全的ArrayList。
1.4 HashSet
HashSet是Set接口的实现,Set不允许元素重复。HashSet基于HashMap实现。
iterator()方法调用HashMap的keySet的iterator方法,HashSet不支持通过get(int)获取指定位置的元素,只能通过iterator方法来获取。
HashSet是非线程安全的。
1.5 TreeSet
TreeSet和HashSet的主要不同在于TreeSet对于排序的支持,TreeSet基于TreeMap实现。add(E)方法调用TreeMap的put方法完成。
TreeSet和HashSet一样,也是完全基于Map来完成的。TreeSet是非线程安全的。
1.6 HashMap
http://blog.youkuaiyun.com/csdnerrrrr/article/details/41287089
1.7 TreeMap
put和get操作基于红黑树实现。TreeMap非线程安全。
在实际的使用中首先要根据功能需求来选择是用List、Set还是Map,List适用于允许重复元素的单个对象集合场景,Set适用于不允许重复元素的单个对象集合场景,Map则适用于key-value结构的集合场景。
在选择好List、Set和Map后,就要选择相应的实现类了,ArrayList适用于要通过位置来读取元素的场景;LinkedList适用于要头尾操作及插入指定位置的场景;Vector适用于要线程安全的ArrayList场景;Stack适用线程安全的LIFO场景。HashSet适用于对排序没有要求的非重复元素的存放;TreeSet适用于要排序的非重复元素的存放;HashMap适用于大部分key-value的存取场景;TreeMap适用于须排序存放的key-value场景。