Java功能丰富的集合类向我们展示了Java在数据结构方面编程的强大功能,而功能如此强大的集合类,正是源自于Java具有的面向对象思想特性。
归纳起来讲,Java的集合可以分为两类,第一类是以数组为代表,这类集合可以描述线性表类型的数据结构,第二类是以Map为代表,这类集合可以描述“键值对”类型的数据结构。
描述第一类数据结构的集合是以Collection为基类,在Collection类里,封装了线性表的插入、删除等基本操作;而数据结构的集合是以Map为基类。两类集合分别通过继承和扩展这两个基类,可以逐渐细化,从而得到诸如堆栈和哈希表之类的数据集合对象。
其中需要了解的集合类和辅助类包括如下:
[table]
|Collections
|
|Arrays
|
|ArrayList
|
|LinkedList
|
|HashMap
|
|LinkedHashMap
|
|TreeMap
|
|WeakHashMap
|
|IdentityHashMap
|
|HashTable
|
|HashSet
|
|LinkedHashSet
|
|TreeSet
|
|EnumMap
|
|EnumSet
|
|BitSet
|
|Vector(可视为动态数组的实现,同时可以实现动态增长的功能)
|
|Stack
|
|Queue(接口)
|
|PriorityQueue
|
|ArrayDeque|
[/table]
其中,Collections 和 Arrays 两个辅助类帮助数组和容器类的排序、复制等等的操作,同时使得两者之间的转换变得如此的得心应手。
EnumMap和EnumSet则是为了枚举类而设置的哈希类,方便使用。
其他的容器类则根据实际情况来使用,不过需要注意的是:
1. List,Map,Set是不同步的(如果多个线程同时访问一个容器类实例,而其中至少一个线程从结构上修改了该实例,则它必须保持外部同步。这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedXXX 方法将该列表“包装”起来。这最好在创建时完成,以防止意外对列表进行不同步的访问。)
2. 快速失败(如果在迭代器创建后的任意时间从结构上修改了容器类实例(通过迭代器自身的 remove 或 add 方法之外的任何其他方式),则迭代器将抛出异常。迭代器很快就完全失败,而不是冒着在将来不确定的时间任意发生不确定行为的风险)
3. BitSet, EnumMap, EnumSet, HashTable不允许插入null值
4. 除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。
5. 在Hash表中,有两个概念是非常重要的:equals 和 hashCode。这两个概念才使得Hash表的实现成为了可能。
6. Map的迭代方式有两种:一是普通的iterator方法来逐一遍历,二是通过entrySet来实现。如:
归纳起来讲,Java的集合可以分为两类,第一类是以数组为代表,这类集合可以描述线性表类型的数据结构,第二类是以Map为代表,这类集合可以描述“键值对”类型的数据结构。
描述第一类数据结构的集合是以Collection为基类,在Collection类里,封装了线性表的插入、删除等基本操作;而数据结构的集合是以Map为基类。两类集合分别通过继承和扩展这两个基类,可以逐渐细化,从而得到诸如堆栈和哈希表之类的数据集合对象。
其中需要了解的集合类和辅助类包括如下:
[table]
|Collections
|
|Arrays
|
|ArrayList
|
|LinkedList
|
|HashMap
|
|LinkedHashMap
|
|TreeMap
|
|WeakHashMap
|
|IdentityHashMap
|
|HashTable
|
|HashSet
|
|LinkedHashSet
|
|TreeSet
|
|EnumMap
|
|EnumSet
|
|BitSet
|
|Vector(可视为动态数组的实现,同时可以实现动态增长的功能)
|
|Stack
|
|Queue(接口)
|
|PriorityQueue
|
|ArrayDeque|
[/table]
其中,Collections 和 Arrays 两个辅助类帮助数组和容器类的排序、复制等等的操作,同时使得两者之间的转换变得如此的得心应手。
EnumMap和EnumSet则是为了枚举类而设置的哈希类,方便使用。
其他的容器类则根据实际情况来使用,不过需要注意的是:
1. List,Map,Set是不同步的(如果多个线程同时访问一个容器类实例,而其中至少一个线程从结构上修改了该实例,则它必须保持外部同步。这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedXXX 方法将该列表“包装”起来。这最好在创建时完成,以防止意外对列表进行不同步的访问。)
2. 快速失败(如果在迭代器创建后的任意时间从结构上修改了容器类实例(通过迭代器自身的 remove 或 add 方法之外的任何其他方式),则迭代器将抛出异常。迭代器很快就完全失败,而不是冒着在将来不确定的时间任意发生不确定行为的风险)
3. BitSet, EnumMap, EnumSet, HashTable不允许插入null值
4. 除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。
5. 在Hash表中,有两个概念是非常重要的:equals 和 hashCode。这两个概念才使得Hash表的实现成为了可能。
6. Map的迭代方式有两种:一是普通的iterator方法来逐一遍历,二是通过entrySet来实现。如:
Map<String,String> map = new HashMap<String,String>(){{
this.put("1", "1"); this.put("2", "2");
this.put("3", "3"); this.put("4", "4");
this.put("5", "5"); this.put("6", "6");
}};
Set<Entry<String, String>> set = map.entrySet();
Iterator<Entry<String, String>> iter = set.iterator();
while(iter.hasNext()){
Entry<String,String> entry = iter.next();
System.out.print("key:"+entry.getKey()+", ");
System.out.println("value:"+entry.getValue());
}