import java.util.Map;
import java.util.HashMap;

public class Hello{

	public static void main(String[] args){
		Map map = new HashMap();

		map.put("Tom", 98);
		map.put("Jack", 89);
		map.put("Marry", 56);
		map.put(null, null);//null可以作为key,value

		//返回98,返回修改后上一次的value,如果是新添加值,返回null
		System.out.println(map.put("Tom", 78));

		System.out.println(map);//{Tom=78, Jack=89, Marry=56}

		System.out.println(map.containsKey("Jack"));//true
		System.out.println(map.containsValue(89));//true

		for(Object key : map.keySet()){
			System.out.println(key+"--->"+map.get(key));
		}
		System.out.println(map.remove("Tom"));//78
		System.out.println(map);//{Jack=89, Marry=56}
	}
}

HashMap线程不安全,可以用Collections工具类包装成线程安全的。与HashSet类似,判断两个key相等的标准也是:两个key通过equals比较返回true,两个key的hashCode值也相等。具体见326页示例代码。

与HashSet类似,如果如果用可变对象作为HashMap的key,并且程序修改了作为key的可变对象,可能会出现和HashSet类似的情况:程序再也无法准确访问到Map中被修改过的key。具体见327页示例代码。

类似于HashSet的LinkedHashSet子类,HashMap也有个子类LinkedHashMap,底层是链表维护的,保证了key的顺序(插入顺序)。


import java.util.LinkedHashMap;

public class Hello{

	public static void main(String[] args){
		LinkedHashMap map = new LinkedHashMap();

		map.put("Tom", 98);
		map.put("Jack", 89);
		map.put("Marry", 56);
		map.put("a", 43);
		map.forEach((key, value)->System.out.println(key+"--->"+value));

	}
}

《疯狂Java讲义(第4版)》-----第8章【Java集合】(Map、Collections)-LMLPHP


具体见329页代码示例。Hashtable和HashMap功能差不多,线程安全,但比较老了,命名都不符合现在Java的命名规范,建议不用。

类比SortedSet接口有TreeSet实现类,SortedMap也有TreeMap实现类。TreeMap也是靠红黑树数据结构来维护键值对的顺序的。TreeMap也有两种排序方式:自然排序和定制排序。

  • 自然排序:TreeMap所有的key必须实现Comparable接口,key是同一类的对象,否则抛异常:ClassCastException
  • 定制排序:创建TreeMap的时候传入一个Comparator对象

类似于TreeSet中判断两个元素相等的标准,TreeMap中判断两个key相等的标准是两个key通过compareTo比较返回值是0。所以如果是自定义类作为TreeMap的key,在自定义类中重写equals和compareTo方法的判定结果要保持一致,以防意外发生。

学到此,发现Map和Set有很多类似的地方。其实,值全为null的Map的keySet不就是Set吗!

Collections工具类提供了对集合操作的方便方法,还可以把线程不安全的集合包装成线程安全的集合(同步控制见339页)。具体参看该书相关章节或Java官方API。

10-04 12:41