HashMap、HashTable、LinkedHashMap和TreeMap用法和区别

来源:互联网 发布:五常知乎 编辑:程序博客网 时间:2024/05/21 11:25
Java为数据结构中的映射定义了一个接口java.util.Map,它有四个实现类,分别是HashMap、HashTable、LinkedHashMap和TreeMap。本节实例主要介绍这4中实例的用法和区别。
关键技术剖析:
Map用于存储键值对,根据键得到值,因此不允许键重复,值可以重复。
l  (1)HashMap是一个最常用的Map,它根据键的hashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为null,不允许多条记录的值为null。HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要同步,可以用Collections.synchronizedMap(HashMap map)方法使HashMap具有同步的能力。
l  (2)Hashtable与HashMap类似,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,然而,这也导致了Hashtable在写入时会比较慢。
l  (3)LinkedHashMap保存了记录的插入顺序,在用Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插入的。在遍历的时候会比HashMap慢。有HashMap的全部特性。
l  (4)TreeMap能够把它保存的记录根据键排序,默认是按升序排序,也可以指定排序的比较器。当用Iteraor遍历TreeMap时,得到的记录是排过序的。TreeMap的键和值都不能为空。

 

[java] view plaincopy
  1. import java.util.HashMap;  
  2. import java.util.Hashtable;  
  3. import java.util.Iterator;  
  4. import java.util.LinkedHashMap;  
  5. import java.util.Map;  
  6. import java.util.TreeMap;  
  7.    
  8.    
  9. public class TestMap {  
  10.     
  11.     
  12.    public static void init(Map map){  
  13.       if (map != null){  
  14.          String key = null;  
  15.          for (int i=5; i>0; i--){  
  16.             key = new Integer(i).toString() + ".0";  
  17.             map.put(key, key.toString());  
  18.             //Map中的键是不重复的,如果插入两个键值一样的记录,  
  19.             //那么后插入的记录会覆盖先插入的记录  
  20.             map.put(key, key.toString() + "0");         }  
  21.       }  
  22.    }  
  23.     
  24.    public static void output(Map map){  
  25.       if (map != null){  
  26.          Object key = null;  
  27.          Object value = null;  
  28.          //使用迭代器遍历Map的键,根据键取值  
  29.          Iterator it = map.keySet().iterator();  
  30.          while (it.hasNext()){  
  31.             key = it.next();  
  32.             value = map.get(key);  
  33.             System.out.println("key: " + key + "; value: " + value );  
  34.          }  
  35.          //或者使用迭代器遍历Map的记录Map.Entry  
  36.          Map.Entry entry = null;  
  37.          it = map.entrySet().iterator();  
  38.          while (it.hasNext()){  
  39.             //一个Map.Entry代表一条记录  
  40.             entry = (Map.Entry)it.next();  
  41.             //通过entry可以获得记录的键和值  
  42.             //System.out.println("key: " + entry.getKey() + "; value: " + entry.getValue());  
  43.          }  
  44.       }  
  45.    }  
  46.     
  47.    public static boolean containsKey(Map map, Object key){  
  48.       if (map != null){  
  49.          return map.containsKey(key);  
  50.       }  
  51.       return false;  
  52.    }  
  53.     
  54.    public static boolean containsValue(Map map, Object value){  
  55.       if (map != null){  
  56.          return map.containsValue(value);  
  57.       }  
  58.       return false;  
  59.    }  
  60.     
  61.    public static void testHashMap(){  
  62.       Map myMap = new HashMap();  
  63.       init(myMap);  
  64.       //HashMap的键可以为null  
  65.       myMap.put(null,"ddd");  
  66.       //HashMap的值可以为null  
  67.       myMap.put("aaa"null);  
  68.       output(myMap);  
  69.    }  
  70.     
  71.    public static void testHashtable(){  
  72.       Map myMap = new Hashtable();  
  73.       init(myMap);  
  74.       //Hashtable的键不能为null  
  75.       //myMap.put(null,"ddd");  
  76.       //Hashtable的值不能为null  
  77.       //myMap.put("aaa", null);  
  78.       output(myMap);  
  79.    }  
  80.     
  81.    public static void testLinkedHashMap(){  
  82.       Map myMap = new LinkedHashMap();  
  83.       init(myMap);  
  84.       //LinkedHashMap的键可以为null  
  85.       myMap.put(null,"ddd");  
  86.       myMap.put(null,"aaa");  
  87.       //LinkedHashMap的值可以为null  
  88.       myMap.put("aaa"null);  
  89.       output(myMap);  
  90.    }  
  91.     
  92.    public static void testTreeMap(){  
  93.       Map myMap = new TreeMap();  
  94.       init(myMap);  
  95.       //TreeMap的键不能为null  
  96.       //myMap.put(null,"ddd");  
  97.       //TreeMap的值不能为null  
  98.       //myMap.put("aaa", null);  
  99.       output(myMap);  
  100.    }  
  101.    
  102.    public static void main(String[] args) {  
  103.       System.out.println("采用HashMap");  
  104.       TestMap.testHashMap();  
  105.       System.out.println("采用Hashtable");  
  106.       TestMap.testHashtable();  
  107.       System.out.println("采用LinkedHashMap");  
  108.       TestMap.testLinkedHashMap();  
  109.       System.out.println("采用TreeMap");  
  110.       TestMap.testTreeMap();  
  111.        
  112.       Map myMap = new HashMap();  
  113.       TestMap.init(myMap);  
  114.       System.out.println("新初始化一个Map: myMap");  
  115.       TestMap.output(myMap);  
  116.       //清空Map  
  117.       myMap.clear();  
  118.       System.out.println("将myMap clear后,myMap空了么?  " + myMap.isEmpty());  
  119.       TestMap.output(myMap);  
  120.       myMap.put("aaa""aaaa");  
  121.       myMap.put("bbb""bbbb");  
  122.       //判断Map是否包含某键或者某值  
  123.       System.out.println("myMap包含键aaa?  "+ TestMap.containsKey(myMap, "aaa"));  
  124.       System.out.println("myMap包含值aaaa?  "+ TestMap.containsValue(myMap, "aaaa"));  
  125.       //根据键删除Map中的记录  
  126.       myMap.remove("aaa");  
  127.       System.out.println("删除键aaa后,myMap包含键aaa?  "+ TestMap.containsKey(myMap, "aaa"));  
  128.       //获取Map的记录数  
  129.       System.out.println("myMap包含的记录数:  " + myMap.size());  
  130.    }  
  131. }  
  132.    
  133. 输出结果:  
  134. 采用HashMap  
  135. key: null; value: ddd  
  136. key: 3.0; value: 3.00  
  137. key: aaa; value: null  
  138. key: 4.0; value: 4.00  
  139. key: 1.0; value: 1.00  
  140. key: 5.0; value: 5.00  
  141. key: 2.0; value: 2.00  
  142. 采用Hashtable  
  143. key: 4.0; value: 4.00  
  144. key: 1.0; value: 1.00  
  145. key: 3.0; value: 3.00  
  146. key: 5.0; value: 5.00  
  147. key: 2.0; value: 2.00  
  148. 采用LinkedHashMap  
  149. key: 5.0; value: 5.00  
  150. key: 4.0; value: 4.00  
  151. key: 3.0; value: 3.00  
  152. key: 2.0; value: 2.00  
  153. key: 1.0; value: 1.00  
  154. key: null; value: aaa  
  155. key: aaa; value: null  
  156. 采用TreeMap  
  157. key: 1.0; value: 1.00  
  158. key: 2.0; value: 2.00  
  159. key: 3.0; value: 3.00  
  160. key: 4.0; value: 4.00  
  161. key: 5.0; value: 5.00  
  162. 新初始化一个Map: myMap  
  163. key: 3.0; value: 3.00  
  164. key: 4.0; value: 4.00  
  165. key: 1.0; value: 1.00  
  166. key: 5.0; value: 5.00  
  167. key: 2.0; value: 2.00  
  168. 将myMap clear后,myMap空了么?  true  
  169. myMap包含键aaa?  true  
  170. myMap包含值aaaa?  true  
  171. 删除键aaa后,myMap包含键aaa?  false  
  172. myMap包含的记录数:  1  
  173.    
  174. 源码分析:  
  175. 遍历Map有两种方法:  
  176. 1)map的keySet()方法获得键的集合,再调用键集合的iterator方法获得键的迭代器,以此迭代地取出Map中的键,用get方法获得键对应的值,便完成了Map的遍历。代码如下所示:  
  177. //使用迭代器遍历Map的键,根据键取值  
  178.         Iterator it = map.keySet().iterator();  
  179.         while (it.hasNext()){  
  180.            key = it.next();  
  181.            value = map.get(key);  
  182.            System.out.println("key: " + key + "; value: " + value );  
  183.         }  
  184. 2)使用Map的entrySet方法获得Map中记录的集合,每条对象都是一个Map.Entry对象,使用其getKey方法获得记录的键,使用其getValue方法获得记录的值。代码如下所示:  
  185.         //或者使用迭代器遍历Map的记录Map.Entry  
  186.         Map.Entry entry = null;  
  187.         it = map.entrySet().iterator();  
  188.         while (it.hasNext()){  
  189.            //一个Map.Entry代表一条记录  
  190.            entry = (Map.Entry)it.next();  
  191.            //通过entry可以获得记录的键和值  
  192.            //System.out.println("key: " + entry.getKey() + "; value: " + entry.getValue());  

http://blog.csdn.net/whuwangyi/article/details/14624653
0 0