实际上,map集合和set集合非常类似,如果把Map集合中所有的Key单独来看,就组成了一个Set集合。事实上,Map中提供了keySet()方法,用于返回由key组成的Set集合。而从源码来看,Java是先实现了Map集合,然后将一个所有value都为null值得Map封装成了Set集合。如果把Map集合中的value当独来看,则与List集合很类似,元素可以重复,可以根据索引(key)来查找。

public class MapTest {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("人生得意须尽欢", 105);
        map.put("莫使金樽空对月", 62);
        map.put("古来圣贤皆寂寞", 88);
        // value值可以重复
        map.put("唯有饮者留其名", 62);
        // 放入重复得key值,会覆盖原有得value值,返回被覆盖value值,62
        System.out.println(map.put("莫使金樽空对月", 10));
        for (Object key : map.keySet()) {
            // 迭代输出key值及对应value值
            System.out.println(key + "-->" + map.get(key));
        }
    }
}

HashMap允许value重复,但是key值不可以重复,如果添加的key-value对中key重复了,新的value会覆盖原来的value,put方法返回原来被覆盖的value。

Hashtable也是Map的实现类,线程安全,key、value不允许存放null,而HashMap则允许。Hashtable类也过于古老,最好不要使用,而是使用Collections工具类将HashMap类变为线程安全的类。

public class NullHashMap {
    public static void main(String[] args) {
        HashMap hm = new HashMap();
        hm.put(null, null);
        hm.put(null, null);
        hm.put("a", null);
        //{null=null, a=null}
        System.out.println(hm);
    }
}

HashMap与Hashtable通过equals()和hashCode()方法比较key值是否相等,通过equals()方法比较value是否相等。

不要使用可变对象作为HashMap、Hashtable的key,否则当key被改变,会造成程序无法访问map集合中key被改变的元素。

class A {
    int count;

    public A(int count) {
        this.count = count;
    }

    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj != null && obj.getClass() == A.class) {
            A a = (A) obj;
            return this.count == a.count;
        }
        return false;
    }
}

public class HashMapErrorTest {
    public static void main(String[] args) {
        HashMap ht = new HashMap();
        ht.put(new A(111), "你若精彩,蝴蝶自来");
        ht.put(new A(12345), "漠漠水田飞白鹭,阴阴夏木啭黄鹂");
        Iterator it = ht.keySet().iterator();
        A first = (A) it.next();
        first.count = 1998;
        // {mapdemo.A@15db9742=你若精彩,蝴蝶自来, mapdemo.A@6d06d69c=漠漠水田飞白鹭,阴阴夏木啭黄鹂}
        System.out.println(ht);
        ht.remove(new A(1998));
        // {mapdemo.A@15db9742=你若精彩,蝴蝶自来, mapdemo.A@6d06d69c=漠漠水田飞白鹭,阴阴夏木啭黄鹂}
        System.out.println(ht);
        // null
        System.out.println(ht.get(new A(1998)));
        // null
        System.out.println(ht.get(new A(111)));
    }
}

LinkeHashMap以双链表来维护集合中key-value对的次序,有利于迭代。

Properties类是Hashtable的子类,相当于一个key、value值都是String类型的Map,主要用于处理属性文件。

public class PropertiesTest {
    public static void main(String[] args) throws FileNotFoundException,
            IOException {
        Properties props = new Properties();
        props.setProperty("username", "banjiu");
        props.setProperty("password", "123456");
        props.store(new FileOutputStream("a.ini"), "comment line");
        Properties props2 = new Properties();
        props2.setProperty("gender", "male");
        //将a.ini文件中的key-value追加到props2中
        //{password=123456, gender=male, username=banjiu}
        props2.load(new FileInputStream("a.ini"));
        System.out.println(props2);
    }
}

Properties类可以把key-value存储至xml文件,也可以从xml文件中读取key-value对,与上示代码类似。