Java集合之Map

  Map 中存放的是键值对。由于Map是按键索引的,因此 key 是不可重复的。但 value 可以重复。

  Map 的常用实现类有,HashMap 、Hashtable 和 TreeMap 。其中 TreeMap 和 TreeSet 很相似,它实现了 SortedMap 接口, SortedMap 继承自 Map 接口。看看 API 会发现 HashMap 和 Hashtable 的方法很相近,构造方法甚至是一样的。我们以前见过几个这样的相似类,比如, StringBuilder 和 StringBuffer 、 ArrayList 和 Vector 。 HashMap 和 Hashtable 也和它们一样。 HashMap 是非线程安全的,而 Hashtable 是线程安全的。但它们的区别不只是这些:

  HashMap 和 Hashtable 的共同之处:
  1、它们都实现了 Map 接口。
  2、它们都是哈希表的实现。

  HashMap 和 Hashtable 的区别:
  1、Hashtable 继承自 Dictionary 类,而 HashMap 继承自 AbstractMap
  2、HashMap 允许将 null 作为 key 或者 value 存储,而 Hashtable 不允许
  3、HashMap 把 Hashtable 的 contains 方法去掉了,改成了 containsvalue 和containsKey 。因为contains方法容易让人引起误解。
  4、最大的不同是, Hashtable 是线程安全的, HashMap 是非线程安全的。

    public void testMap() {
        Map<String, String> info = new HashMap<String, String>();
        info.put("username", "Little");
        info.put("password", "hello, world");
        info.put("email", "[email protected]");
        info.put("phone", "110");
        info.put("nothing", "error");
        info.put(null, "the key is null"); // key为null
        info.put("the value is null", null); // value为null
        display(info);

        System.out.println("--- Remove 'error':" 
                + info.remove("error") + " ---");
        display(info);

        System.out.println("--- Remove 'nothing':'" 
                + info.remove("nothing") + "' ---");
        display(info);

        System.out.println("--- Replace 'password':'" 
                + info.put("password", "new, world") + "' ---");
        display(info);
    }

    public void display(Map map) {
        if (map == null) {
            System.out.println("[null]");
            return;
        }
        
        Set keys = map.keySet();
        for (Object key : keys) {
            System.out.println("<" + key + " = " + map.get(key) + ">");
        }
        System.out.println("Size: " + map.size());
    }


  我们可以尝试用 Hashtable 来实现这段代码,但是,当存入 null 键或者 null 值时(即代码中带注释的两行),都会抛出 NullPointerException ,因为 Hashtable 不允许存放 null 键或 null 值。

  到现在,我们已经学习了三个 JDK 中哈希表的实现: HashSet、HashMap 和 Hashtable 。实际上, HashSet 的底层就是用 HashMap 来做的。这可以和我们写的 MyStack 比较来理解,MyStack 内部是使用 ArrayList 来存数数据,操作也是“委托”给 ArrayList 来做的。 HashSet 也是这个原理,只是 HashSet “委托”给 HashMap 来做。Set的另外一个实现类 TreeSet 也使用了这种方式,它底层使用 TreeMap 来做的。这种方式体现了面向对象的封装性。

你可能感兴趣的:(java,jdk)