在使用
Java
的时候,我们都会遇到使用集合(
Collection
)的时候,但是
Java API
提供了多种集合的实现,我在使用和面试的时候频频遇到这样的
“
抉择
”
。
:
)(主要还是面试的时候)
久而久之,也就有了一点点的心得体会,写出来以供大家讨论 。
总的说来, Java API 中所用的集合类,都是实现了 Collection 接口,他的一个类继承结构如下:
Collection<--List<--Vector
Collection<--List<--ArrayList
Collection<--List<--LinkedList
Collection<--Set<--HashSet
Collection<--Set<--HashSet<--LinkedHashSet
Collection<--Set<--SortedSet<--TreeSet
Vector : 基于 Array 的 List ,其实就是封装了 Array 所不具备的一些功能方便我们使用,它不可能走入 Array 的限制。性能也就不可能超越 Array 。所以,在可能的情况下,我们要多运用 Array 。另外很重要的一点就是 Vector“sychronized” 的,这个也是 Vector 和 ArrayList 的唯一的区别。
ArrayList :同 Vector 一样是一个基于 Array 上的链表,但是不同的是 ArrayList 不是同步的。所以在性能上要比 Vector 优越一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。
LinkedList : LinkedList 不同于前面两种 List ,它不是基于 Array 的,所以不受 Array 性能的限制。它每一个节点( Node )都包含两方面的内容: 1. 节点本身的数据( data ); 2. 下一个节点的信息( nextNode )。所以当对 LinkedList 做添加,删除动作的时候就不用像基于 Array 的 List 一样,必须进行大量的数据移动。只要更改 nextNode 的相关信息就可以实现了。这就是 LinkedList 的优势。
List 总结:
1. 所有的 List 中只能容纳单个不同类型的对象组成的表,而不是 Key - Value 键值对。例如: [ tom,1,c ] ;
2. 所有的 List 中可以有相同的元素,例如 Vector 中可以有 [ tom,koo,too,koo ] ;
3. 所有的 List 中可以有 null 元素,例如 [ tom,null,1 ] ;
4. 基于 Array 的 List ( Vector , ArrayList )适合查询,而 LinkedList (链表)适合添加,删除操作。
HashSet :虽然 Set 同 List 都实现了 Collection 接口,但是他们的实现方式却大不一样。 List 基本上都是以 Array 为基础。但是 Set 则是在 HashMap 的基础上来实现的,这个就是 Set 和 List 的根本区别。 HashSet 的存储方式是把 HashMap 中的 Key 作为 Set 的对应存储项。看看 HashSet 的 add ( Object obj )方法的实现就可以一目了然了。
public boolean add(Object obj)
{
return map.put(obj, PRESENT) == null;
}
这个也是为什么在 Set 中不能像在 List 中一样有重复的项的根本原因,因为 HashMap 的 key 是不能有重复的。
LinkedHashSet : HashSet 的一个子类,一个链表。
TreeSet : SortedSet 的子类,它不同于 HashSet 的根本就是 TreeSet 是有序的。它是通过 SortedMap 来实现的。
Set 总结:
1. Set 实现的基础是 Map ( HashMap );
2. Set 中的元素是不能重复的,如果使用 add(Object obj) 方法添加已经存在的对象,则会覆盖前面的对象;
久而久之,也就有了一点点的心得体会,写出来以供大家讨论 。
总的说来, Java API 中所用的集合类,都是实现了 Collection 接口,他的一个类继承结构如下:
Collection<--List<--Vector
Collection<--List<--ArrayList
Collection<--List<--LinkedList
Collection<--Set<--HashSet
Collection<--Set<--HashSet<--LinkedHashSet
Collection<--Set<--SortedSet<--TreeSet
Vector : 基于 Array 的 List ,其实就是封装了 Array 所不具备的一些功能方便我们使用,它不可能走入 Array 的限制。性能也就不可能超越 Array 。所以,在可能的情况下,我们要多运用 Array 。另外很重要的一点就是 Vector“sychronized” 的,这个也是 Vector 和 ArrayList 的唯一的区别。
ArrayList :同 Vector 一样是一个基于 Array 上的链表,但是不同的是 ArrayList 不是同步的。所以在性能上要比 Vector 优越一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。
LinkedList : LinkedList 不同于前面两种 List ,它不是基于 Array 的,所以不受 Array 性能的限制。它每一个节点( Node )都包含两方面的内容: 1. 节点本身的数据( data ); 2. 下一个节点的信息( nextNode )。所以当对 LinkedList 做添加,删除动作的时候就不用像基于 Array 的 List 一样,必须进行大量的数据移动。只要更改 nextNode 的相关信息就可以实现了。这就是 LinkedList 的优势。
List 总结:
1. 所有的 List 中只能容纳单个不同类型的对象组成的表,而不是 Key - Value 键值对。例如: [ tom,1,c ] ;
2. 所有的 List 中可以有相同的元素,例如 Vector 中可以有 [ tom,koo,too,koo ] ;
3. 所有的 List 中可以有 null 元素,例如 [ tom,null,1 ] ;
4. 基于 Array 的 List ( Vector , ArrayList )适合查询,而 LinkedList (链表)适合添加,删除操作。
HashSet :虽然 Set 同 List 都实现了 Collection 接口,但是他们的实现方式却大不一样。 List 基本上都是以 Array 为基础。但是 Set 则是在 HashMap 的基础上来实现的,这个就是 Set 和 List 的根本区别。 HashSet 的存储方式是把 HashMap 中的 Key 作为 Set 的对应存储项。看看 HashSet 的 add ( Object obj )方法的实现就可以一目了然了。
public boolean add(Object obj)
{
return map.put(obj, PRESENT) == null;
}
这个也是为什么在 Set 中不能像在 List 中一样有重复的项的根本原因,因为 HashMap 的 key 是不能有重复的。
LinkedHashSet : HashSet 的一个子类,一个链表。
TreeSet : SortedSet 的子类,它不同于 HashSet 的根本就是 TreeSet 是有序的。它是通过 SortedMap 来实现的。
Set 总结:
1. Set 实现的基础是 Map ( HashMap );
2. Set 中的元素是不能重复的,如果使用 add(Object obj) 方法添加已经存在的对象,则会覆盖前面的对象;