Map
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
HashMap线程不安全,可以用Collections工具类包装成线程安全的。与HashSet类似,判断两个key相等的标准也是:两个key通过equals比较返回true,两个key的hashCode值也相等。具体见326页示例代码。
与HashSet类似,如果如果用可变对象作为HashMap的key,并且程序修改了作为key的可变对象,可能会出现和HashSet类似的情况:程序再也无法准确访问到Map中被修改过的key。具体见327页示例代码。
LinkedHashMap
类似于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));
}
}
Properties是Hashtable的子类,可以向XML等文件存取键值对
具体见329页代码示例。Hashtable和HashMap功能差不多,线程安全,但比较老了,命名都不符合现在Java的命名规范,建议不用。
SortedMap与TreeMap
类比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工具类
Collections工具类提供了对集合操作的方便方法,还可以把线程不安全的集合包装成线程安全的集合(同步控制见339页)。具体参看该书相关章节或Java官方API。