我们在学校时就知道常用的数据结构,顺序容器数组,链表,队列(先进先出),栈(先进后出),去重容器,关联容器,哈希表。所以就以这些作为切入java容器的入口,而且平常的代码编写中基本上也就用到这些容器而已
这些容器在java中都有提供的标准容器类
顺序容器数组 List
链表 LinkedList
队列 Queue
栈 Stack
去重容器 Set
关联容器 Map
哈希表 HashTable
这些看起来有点乱,其实整个继承体系分两路,一路是Map和变种Map的共同父类是Map,另一个就是其他容器的共同父类是Collection。继承结构如下:
Collection
List
ArrayList 动态扩展的顺序数组容器,也是java中最常用的容器
LinkedList 链表容器
Vector 线程安全的动态数组容器
Stack 栈容器
Set
HashSet java中最常用的Set容器
Queue 队列
Map
HashMap java中最常用的关联容器
HashTable 线程安全的哈希表
Java常用容器就这些了,值得一提的是java并没提供标准的树结构的容器,另外关于线程安全的问题,也是使用容器时一大烦恼。在这里如果要记忆哪些容器是否是线程安全的比较费脑细胞,还好java提供了简单易用的装饰模式来包装任何线程不安全的线程类。
Collections.synchronizedCollection(c)//c为Collection的子类对象
Collections.synchronizedList(list)//list为List的子类对象
Collections.synchronizedSet(s)//s为Set的子类对象
Collections.synchronizedMap(m)//m为Map的子类对象
也就是说即使记不住线程安全的子类容器的名字,直接用上述方法封装下一般的容器也能得到返回的线程安全的容器对象的引用。这样,妈妈再也不用担心我的线程安全了。这里面用到了装饰模式,还有线程安全的同步锁机制,比如被Collections.synchronizedMap(m)封装后的线程安全Map对象调用put方法时,源码的实现如下,用synchronized进行了加锁,避免了多线程争用资源的情况,保障线程安全。
publicV put(K key, V value) {
synchronized(mutex) {return m.put(key, value);}
}
关于线程安全和装饰模式出门左转看<对java多线程的线程安全性的一些总结>和<Java实际应用中经常遇到的"装饰模式"总结>两篇文章。