`
高军威
  • 浏览: 181993 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多
原文转载:http://www.open-open.com/lib/view/open1350440858024.html

Java为数据结构中的映射定义了一个接口java.util.Map,它有四个实现类,分别是HashMap、HashTable、LinkedHashMap和TreeMap。本节实例主要介绍这4中实例的用法和区别。

关键技术剖析:Map用于存储键值对,根据键得到值,因此不允许键重复,值可以重复。
(1)HashMap是一个最常用的Map,它根据键的hashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为null,不允许多条记录的值为null。HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要同步,可以用Collections.synchronizedMap(HashMap map)方法使HashMap具有同步的能力。
(2)Hashtable与HashMap类似,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,然而,这也导致了Hashtable在写入时会比较慢。
(3)LinkedHashMap保存了记录的插入顺序,在用Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插入的。在遍历的时候会比HashMap慢。有HashMap的全部特性。
(4)TreeMap能够把它保存的记录根据键排序,默认是按升序排序,也可以指定排序的比较器。当用Iteraor遍历TreeMap时,得到的记录是排过序的。TreeMap的键和值都不能为空。

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
 
 
public class TestMap {
  
  
   public static void init(Map map){
      if (map != null){
         String key = null;
         for (int i=5; i>0; i--){
            key = new Integer(i).toString() + ".0";
            map.put(key, key.toString());
            //Map中的键是不重复的,如果插入两个键值一样的记录,
            //那么后插入的记录会覆盖先插入的记录
            map.put(key, key.toString() + "0");         }
      }
   }
  
   public static void output(Map map){
      if (map != null){
         Object key = null;
         Object value = null;
         //使用迭代器遍历Map的键,根据键取值
         Iterator it = map.keySet().iterator();
         while (it.hasNext()){
            key = it.next();
            value = map.get(key);
            System.out.println("key: " + key + "; value: " + value );
         }
         //或者使用迭代器遍历Map的记录Map.Entry
         Map.Entry entry = null;
         it = map.entrySet().iterator();
         while (it.hasNext()){
            //一个Map.Entry代表一条记录
            entry = (Map.Entry)it.next();
            //通过entry可以获得记录的键和值
            //System.out.println("key: " + entry.getKey() + "; value: " + entry.getValue());
         }
      }
   }
  
   public static boolean containsKey(Map map, Object key){
      if (map != null){
         return map.containsKey(key);
      }
      return false;
   }
  
   public static boolean containsValue(Map map, Object value){
      if (map != null){
         return map.containsValue(value);
      }
      return false;
   }
  
   public static void testHashMap(){
      Map myMap = new HashMap();
      init(myMap);
      //HashMap的键可以为null
      myMap.put(null,"ddd");
      //HashMap的值可以为null
      myMap.put("aaa", null);
      output(myMap);
   }
  
   public static void testHashtable(){
      Map myMap = new Hashtable();
      init(myMap);
      //Hashtable的键不能为null
      //myMap.put(null,"ddd");
      //Hashtable的值不能为null
      //myMap.put("aaa", null);
      output(myMap);
   }
  
   public static void testLinkedHashMap(){
      Map myMap = new LinkedHashMap();
      init(myMap);
      //LinkedHashMap的键可以为null
      myMap.put(null,"ddd");
      myMap.put(null,"aaa");
      //LinkedHashMap的值可以为null
      myMap.put("aaa", null);
      output(myMap);
   }
  
   public static void testTreeMap(){
      Map myMap = new TreeMap();
      init(myMap);
      //TreeMap的键不能为null
      //myMap.put(null,"ddd");
      //TreeMap的值不能为null
      //myMap.put("aaa", null);
      output(myMap);
   }
 
   public static void main(String[] args) {
      System.out.println("采用HashMap");
      TestMap.testHashMap();
      System.out.println("采用Hashtable");
      TestMap.testHashtable();
      System.out.println("采用LinkedHashMap");
      TestMap.testLinkedHashMap();
      System.out.println("采用TreeMap");
      TestMap.testTreeMap();
     
      Map myMap = new HashMap();
      TestMap.init(myMap);
      System.out.println("新初始化一个Map: myMap");
      TestMap.output(myMap);
      //清空Map
      myMap.clear();
      System.out.println("将myMap clear后,myMap空了么?  " + myMap.isEmpty());
      TestMap.output(myMap);
      myMap.put("aaa", "aaaa");
      myMap.put("bbb", "bbbb");
      //判断Map是否包含某键或者某值
      System.out.println("myMap包含键aaa?  "+ TestMap.containsKey(myMap, "aaa"));
      System.out.println("myMap包含值aaaa?  "+ TestMap.containsValue(myMap, "aaaa"));
      //根据键删除Map中的记录
      myMap.remove("aaa");
      System.out.println("删除键aaa后,myMap包含键aaa?  "+ TestMap.containsKey(myMap, "aaa"));
      //获取Map的记录数
      System.out.println("myMap包含的记录数:  " + myMap.size());
   }
}
 
输出结果:
采用HashMap
key: null; value: ddd
key: 3.0; value: 3.00
key: aaa; value: null
key: 4.0; value: 4.00
key: 1.0; value: 1.00
key: 5.0; value: 5.00
key: 2.0; value: 2.00
采用Hashtable
key: 4.0; value: 4.00
key: 1.0; value: 1.00
key: 3.0; value: 3.00
key: 5.0; value: 5.00
key: 2.0; value: 2.00
采用LinkedHashMap
key: 5.0; value: 5.00
key: 4.0; value: 4.00
key: 3.0; value: 3.00
key: 2.0; value: 2.00
key: 1.0; value: 1.00
key: null; value: aaa
key: aaa; value: null
采用TreeMap
key: 1.0; value: 1.00
key: 2.0; value: 2.00
key: 3.0; value: 3.00
key: 4.0; value: 4.00
key: 5.0; value: 5.00
新初始化一个Map: myMap
key: 3.0; value: 3.00
key: 4.0; value: 4.00
key: 1.0; value: 1.00
key: 5.0; value: 5.00
key: 2.0; value: 2.00
将myMap clear后,myMap空了么?  true
myMap包含键aaa?  true
myMap包含值aaaa?  true
删除键aaa后,myMap包含键aaa?  false
myMap包含的记录数:  1


源码分析:

遍历Map有两种方法:
(1)map的keySet()方法获得键的集合,再调用键集合的iterator方法获得键的迭代器,以此迭代地取出Map中的键,用get方法获得键对应的值,便完成了Map的遍历。代码如下所示:
//使用迭代器遍历Map的键,根据键取值
        Iterator it = map.keySet().iterator();
        while (it.hasNext()){
           key = it.next();
           value = map.get(key);
           System.out.println("key: " + key + "; value: " + value );
        }
(2)使用Map的entrySet方法获得Map中记录的集合,每条对象都是一个Map.Entry对象,使用其getKey方法获得记录的键,使用其getValue方法获得记录的值。代码如下所示:
        //或者使用迭代器遍历Map的记录Map.Entry
        Map.Entry entry = null;
        it = map.entrySet().iterator();
        while (it.hasNext()){
           //一个Map.Entry代表一条记录
           entry = (Map.Entry)it.next();
           //通过entry可以获得记录的键和值
           //System.out.println("key: " + entry.getKey() + "; value: " + entry.getValue());
分享到:
评论

相关推荐

    java中HashMap,LinkedHashMap,TreeMap,HashTable的区别

    ### Java中HashMap, LinkedHashMap, TreeMap,HashTable的区别 在Java编程语言中,`Map`接口是集合框架中的一个重要组成部分,用于存储键值对。本文将详细分析四种常用的`Map`实现类:`HashMap`, `LinkedHashMap`, ...

    HashMap,HashTable,LinkedHashMap,TreeMap的区别

    HashMap, HashTable, LinkedHashMap, TreeMap 的区别 在 Java 中,Map 是一个非常重要的集合类,用于存储键值对。其中,HashMap, HashTable, LinkedHashMap, TreeMap 是四种常用的 Map 实现类,每种类都有其特点和...

    java HashMap,TreeMap与LinkedHashMap的详解

    在示例中,`HashMap`、`Hashtable`和`TreeMap`的使用方式类似,但它们的行为不同。`Hashtable`与`HashMap`类似,但它是线程安全的,并且不接受null值。而`TreeMap`则根据键的自然顺序对键值对进行了排序。 ```java ...

    Java集合专题总结:HashMap 和 HashTable 源码学习和面试总结

    Map接口用于保存具有key-value映射关系的数据,常见的Map实现包括HashMap、TreeMap、HashTable和LinkedHashMap等。Queue是Java提供的队列实现。 本文总结了HashMap和HashTable的源码学习和面试总结,涵盖了它们的...

    第9讲 对比Hashtable、HashMap、TreeMap有什么不同?1

    HashMap、Hashtable和TreeMap都是Java中实现Map接口的类,它们用于存储键值对数据,但各自具有不同的特点和使用场景。 HashMap是最常用的Map实现,它通过哈希表(散列表)实现,提供快速的插入、查找和删除操作,...

    HashMap vs TreeMap vs Hashtable vs LinkedHashMap

    HashMap是最常用的Map实现,它提供了快速的查找,但不保证元素的顺序,且允许null键和值。TreeMap则按Key的自然排序或自定义排序存储元素,适合需要排序的场景。HashTable是线程安全的,但效率相对较低,不推荐在单...

    Collection,List,Set和_Map用法和区别

    Map 的实现类有 Hashtable、HashMap、LinkedHashMap 和 TreeMap。Hashtable 是一种线程安全的哈希表,HashMap 是一种线程不安全的哈希表,LinkedHashMap 是一种链表哈希表,TreeMap 是一种树形哈希表。 在实际应用...

    Java面试的10个问题(含参考答案).docx

    Map接口是双列集合,存储键值对,例如Hashtable、HashMap、LinkedHashMap和TreeMap。Hashtable是线程安全的,HashMap非线程安全但性能较高,LinkedHashMap保持插入顺序,TreeMap则根据键进行排序。 在SQL中,事务...

    Java容器有两种基本类型Collection 和 Map

    在使用散列的数据结构(HashSet、HashMap、LinkedHashSet 或者 LinkedHashMap)时,最好先覆盖 hashCode() 和 equals(),因为从 Object 继承下来的 hashCode() 方法默认是使用对象的地址计算散列值。 hashCode 对于...

    HashMap底层原理.pdf

    本文将详细介绍HashMap的底层原理,包括其内部实现结构、关键字段的作用、以及JDK 1.7和JDK 1.8版本的主要区别。 首先,HashMap是基于哈希表的Map接口非同步实现,它允许使用null值和null键,这意味着HashMap在设计...

    java集合详解与总结.pdf

    7. HashMap和Hashtable的主要区别在于线程安全性,HashMap是非同步的,性能较高,而Hashtable是线程安全的,但在多线程环境下使用时无需手动同步,但性能相对较低。 8. Java 1.5引入了泛型,使得集合在编译时就能...

    java7hashmap源码-learning-record:学习轨迹记录

    HashTable和HashMap的区别详解 LeetCode 27. 删除元素(Remove Element) 7月8号 7月5号 复习hashMap concurrentHashmap [LeetCode 70. 爬楼梯(Climbing Stairs).md](Java基础/数据结构与算法/LeetCode/LeetCode ...

    java面试笔记.pdf

    4. HashMap和TreeMap的区别: - TreeMap实现了SortedMap接口,基于红黑树,而HashMap基于哈希散列表实现。 - TreeMap插入、删除速度慢,因为需要维护树的平衡。 - TreeMap默认按键的升序排序,而HashMap是随机存储。...

    Java集合框架常见面试题.pdf

    而Hashtable是线程安全的Map实现,但已被推荐使用synchronized关键字配合HashMap来替代,因为它的性能较低。 Java集合框架还提供了一些高级特性和工具类,如CopyOnWriteArrayList、ConcurrentHashMap等,它们在多...

    HashMapvs.TreeMapvs.Hashtable

    在Java编程语言中,`HashMap`、`TreeMap`和`Hashtable`是三种常见的集合类,它们都实现了`Map`接口,用于存储键值对数据。理解这些类的区别和应用场景对于提升Java开发技能至关重要。 首先,`HashMap`是Java中最...

    Hashtable的使用

    `Hashtable`与`HashMap`的区别 - **线程安全性**:`Hashtable`是线程安全的,而`HashMap`不是。 - **允许`null`值**:`HashMap`允许一个`null`键和多个`null`值,而`Hashtable`都不允许。 - **迭代器遍历顺序**:`...

    java的hashtable的用法.pdf

    自Java 5开始,`java.util.Map`接口和它的实现如`HashMap`、`TreeMap`提供了更灵活和高效的选择。特别是`ConcurrentHashMap`,它在多线程环境中提供了高性能的并发访问。 9. **非序性**: 和`HashMap`一样,`...

    2021-3月Java面试题.docx

    主要实现类有HashMap、LinkedHashMap、TreeMap和Hashtable。 - HashMap是基于哈希表的数据结构,JDK1.8以前是数组+链表,JDK1.8后引入了红黑树,当链表长度达到8时转换为红黑树,提高了查找效率。 - LinkedHashMap...

    Java集合框架全面介绍.pdf

    Map接口的实现包括HashMap、LinkedHashMap、TreeMap和Hashtable。HashMap是最常用的实现,它提供了快速的查找和插入,但不保证元素顺序。LinkedHashMap保持了插入顺序或访问顺序,而TreeMap按照键的自然排序或比较器...

    Java集合框架详解

    主要实现类包括HashMap、Hashtable、LinkedHashMap和TreeMap。 1. HashMap:它利用键的hashCode值存储数据,根据键快速定位到值。由于使用了哈希表的存储方式,HashMap通常能够提供较快的读写性能。它的遍历顺序是...

Global site tag (gtag.js) - Google Analytics