HashMap
允许设置key和value为null,key存放是乱序的,不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap,访问速度快,因为它根据key的HashCode 值来存储数据
public static void main(String[] args) { System.out.println("************************* HashMap *******************************"); HashMap<String, String> hashMap = new HashMap<String, String>(); hashMap.put("X-rapido", "Admin"); hashMap.put("X-rapido", "User"); // 重复的会替换旧数据 hashMap.put("Y-miya", null); hashMap.put("J-lina", null); System.out.println(hashMap.get(null)); hashMap.put(null, "Manager"); hashMap.put(null, "liner"); hashMap.put("X", "好帅"); hashMap.put("PrettyBoy", "X-rapido"); System.out.println(hashMap.get(null) + " : " + hashMap.get("X-rapido") + "\n"); for (String key : hashMap.keySet()) { System.out.println(key + " : " + hashMap.get(key)); } } 结果 ************************* HashMap ******************************* null liner : 好帅 null : liner J-lina : null Y-miya : null X-rapido : User PrettyBoy : X-rapido X : 好帅
TreeMap
不允许key为null,但允许value为null,线程非同步,存放是根据key默认是升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。
public static void main(String[] args) { System.out.println("************************* TreeMap *******************************"); TreeMap<String, String> treeMap = new TreeMap<String, String>(); treeMap.put("X-rapido", "Admin"); treeMap.put("X-rapido", "User"); // 重复的会替换旧数据 treeMap.put("Y-miya", null); treeMap.put("J-lina", null); System.out.println(treeMap.get(null)); treeMap.put(null, "Manager"); }
结果
************************* TreeMap *******************************
Exception in thread "main" java.lang.NullPointerException
at java.util.TreeMap.getEntry(TreeMap.java:324)
at java.util.TreeMap.get(TreeMap.java:255)
at com.founder.MapSoft.main(MapSoft.java:32)
正确代码
System.out.println("************************* TreeMap *******************************"); TreeMap<String, String> treeMap = new TreeMap<String, String>(); treeMap.put("X-rapido", "Admin"); treeMap.put("X-rapido", "User"); // 重复的会替换旧数据 treeMap.put("Y-miya", null); treeMap.put("J-lina", null); treeMap.put("X", "好帅"); treeMap.put("PrettyBoy", "X-rapido"); for (String key : treeMap.keySet()) { System.out.println(key+" : "+treeMap.get(key)); } 结果 ************************* TreeMap ******************************* J-lina : null PrettyBoy : X-rapido X-rapido : User Y-miya : null X : 好帅
可以使用System.out.println(treeMap.firstEntry().getKey());和System.out.println(treeMap.firstKey());获取排完序之后的第一个key和value
Hashtable
key和value都不允许为null,线程同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢
HashMap和HashTable的区别主要有以下几个方面
HashTable的方法是同步的,HashMap不能同步
HashTable不允许为null(key和value都不可以),HashMap允许null值(key和value都可以)
HashTable有一个contains()方法,功能和containsValue()功能一样。
HashTable使用Enumeration遍历,HashMap使用Iterator遍历。
HashTable中hash数组的初始化大小及其增长方式不同。(hashTable默认hash数组是11,增长方式是:old*2+1,hashMap默认大小是16,增长方式一定是2的指数)
哈希值的使用不同,HashTable直接使用对象的hashCode,而HashMap会重新计算hash值。
LinkedHashMap
保存插入的顺序,线程非同步,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的
不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap
实现类 | Map | |||
继承类 | AbstractMap | Dictionary | AbstractMap | HashMap |
名称 | HashMap | HashTable | TreeMap | LinkedHashMap |
是否有序排列 | n(随机的) | n | y (默认升序) | y(按插入顺序排列) |
线程是否同步 | n | y | n | n |
允许Key为null | y | n | n | y |
允许Value为null | y | n | y | y |
性能 | 快(HashMap的遍历速度和他的容量有关) | 慢 | 块 | 慢(遍历速度只和实际数据有关,和容量无关) |
应用范围 | 插入、删除和定位元素,HashMap是最好的选择 | 线程安全 | 取出来的是排序后的键值对,插入、删除需要维护平衡会牺牲一些效率 | 需要输出的顺序和输入的顺序相同 |
Java Map集合利用比较器Comparator根据Key和Value的排序
未经允许请勿转载:程序喵 » 【Java】HashMap、TreeMap、Hashtable、LinkedHashMap区别