目录导读:
- Map 概述
- HashMap(线程不安全)
- LinkedHashMap
- Hashtable(线程安全)
- Properties(可用于读写属性文件,如ini文件)
- TreeMap(类比于TreeSet)
- WeakHashMap
- IdentityHashMap
- EnumMap
- 各个Map实现类的性能分析
1.Map 概述
Map 保存的是键值对数据的集合,也被称为字典,或关联数组
Map类似于一个瓶子,因此,里面的元素不允许重复, 且无序的。
将Map的key-value中的key单独拿出来看时,它们就是一个Set集合,故不可以重复
value单独拿出来看时,它们类似一个List集合(可以重复,可以为null),只是索引不再是整数值,而是另一个对象key
注意:
HashMap允许有一个null作为key
Hastable不允许null做为其key和value
1.Map 集合的操作
由于是key-value,则操作时针对key和value的一些增、删、判断等
(1)增
Object put(Object key, Object value); //添加一个key-value对,如Map中已存在key,则新的键值对会覆盖原来的键值对,并返回被覆盖的value
void putAll(Map m); //将m中的键值对复制到本Map中
(2)删
void clear(); //删除该Map对象中的所有key-value对
Object remove(Object key); //删除指定key所对应的键值对,并返回该键值对的值,若key不存在,则返回null
boolean remove(Object key, Object value); //Java8新增的方法,删除指定的key-value,
(3)判断
boolean containsKey(Object key); //判断Map中是否有指定的key,有则返回true
boolean containsValue(Object value); //判断Map中是否包含一个或多个value
boolean isEmpty(); //判断该Map是否为空
(4)获取
Object get(Object key); //返回指定key所对应的value,若不包含该key则返回null
int size(); //返回Map里键值对的个数,即元素个数
Set keySet(); //返回该Map中的所有key组成的Set集合
Collection values(); //返回该Map里所有的value组成的Collection
Set<Map.Entry<K,V>> entrySet(); //返回key-value对所组成的Set集合,每个集合元素都是Map.Entry对象
注:Entry是Map对象的内部类,该类封装了一个key-value对,Entry包含如下三个方法:
1.Object getKey(); //返回Entry里包含的key值
2.Object getValue(); //返回Entry里包含的value
3.Object setValue(V value); //设置Entry里包含的value值,并返回新设置的value值
(5)遍历
就要借助上面的提到的方法,再结合foreach循环即可完成遍历
Set keySet(); //返回该Map中的所有key组成的Set集合
2.HashMap 和 Hashtable 实现类
它们都是Map接口的典型实现类,Hashtable是个古老的类(从名字里就可以看出的),线程安全
Hashtable和HashMap的区别?
1.Hashtable是线程安全,HashMap是线程不安全的,因此,HashMap的性能好一点。但对于多线程
情况下,Hashtable会更好。但为了达到线程安全,建议使用Collections工具类将HashMap包装成线程安全的
2.Hashtable不允许null做为key和value,如果将null作为key或value放入Hashtable均会引
发java.lang.NullPointerException; HashMap则可以将null作为key或value存入, 且key只能有一个为null,
value可以有无数多个
为了成功的在Hashtable和HashMap中存储、获取对象,用作key的对象必须实现hashCode()和equals()方法(尤其是那些自定义的类)
Hashtable和HashMap判断两个key相等的标准是:两个key通过equals()返回true,且hashCode()返回值也相等
Hashtable和HashMap判断两个value相等的标准是: 同equals()方法比较返回true即可
3.LinkedHashMap 实现类
是HashMap的子类,同LinkedHashSet一样,也是双向链表来维护key-value对的次序,
由于它是有序,如果添加元素时按顺序添加,就可"排序"访问,这就省去了用HashMap和Hashtable存储后再进行排序的尴尬。
由于需要维护其插入顺序,因此,性能略低与HashMap。但在迭代访问Map里的全部元素时有较好的性能(因为内部是链表维护的顺序)
4.Properties 类
是Hashtable的子类,用于处理属性文件的。它在Map对象和属性文件之间起桥梁作用
相关方法:
String getProperty(String key); // 获取Properties中指定属性名对应的属性值
String getProperty(String key, String defaultValue); //与前面的方法类似,只是如果该key不存在,则返回该默认值defaultValue
Object setProperty(String key, String value); //设置属性值
//读写属性文件的方法
void load(InputStream inStream); //从属性文件中加载key-value对大Properties里
void store(OutputStream out, String comments); //将Properties中的key-value输出到指定的属性文件中,comments是注释次信息
5.TreeMap 实现类
·如同Set接口派生出了SortedSet接口一样,Map接口也派生出了SortedMap接口,其实现类:TreeMap
·由于TreeMap具有排序性,因此在Map方法的基础上增加了一些访问第一个、最后一个、截取某部分等的方法
如:
Map.Entry firstEntry(); //返回该Map中最小的key对应的key-value对,若为空,返回null
Object firstKey(); //返回Map中最小key值,如为空,返回null
Map.Entry lastEntry();
Object lastKey();
SortedMap subMap(Object fromKey, Object toKey); //
·TreeMap同行TreeSet一样也有两种排序状态:
自然排序:
定制排序:
6.WeakHashMap 实现类
用法基本同HashMap,只是它的key保留了对实际对象的弱引用。而HashMap的key保留了对实际对象的强引用,
即只要该HashMap对象不被销毁,该HashMap的所有key引用的对象就不会被垃圾回收,HashMap也不会自动删除
这些key所对应的key-value对。而WeakHashMap对象的key所引用的对象如果没有被其他变量强引用,则这些key
所引用的对象可能被垃圾回收,WeakHashMap也可能自动删除这些key所对应的key-value对。
注意:
1.不要让WeakHashMap的key所引用的对象具有任何强饮用,否则将失去WeakHashMap的意义
WeakHashMap whm = new WeakHashMap();
whm.put("java", new String("200")); //具有强引用, "java"
whm.put(new String("android"), new String("200")); //弱引用
7.IdentityHashMap 实现类
用法基本同HashMap,只是它在处理两个key是否相等时等价严格:当且仅当 key1==key2 时,才认为它们相等
普通的HashMap则只要key1和key2通过equals()方法返回true,hashCode()值相等即可。
如:
IdentityHashMap ith = new IdentityHashMap();
ith.put(new String("java"), 78);
ith.put(new String("java"), 45); //两个均能添加进去,因为是new的,肯定不相等,便认为是两个对象
ith.put("android", 45);
ith.put("android", 51); //只能存在一个(最后这个)
8.EnumMap 实现类
·添加的key-value对的key须是枚举类的枚举值。
·按枚举类中的顺序维护key的有序性
·不允许null作为key,否则引发NullPointerException异常;如果查询是否包含null的key,或删除值为null的key,都不会抛异常(尽管不会成功)
·内部以数组形式保存key-value,因此很高效,紧凑
9.各个Map实现类的性能分析
1.HashMap和Hashtable的实现机制几乎一样(都是基于hash算法),但Hashtable是一个古老、线程安全的类,因此
性能不如HashMap
2.TreeMap底层是基于红黑树实现,要维护key-value的有序性,因此性能不如HashMap和Hashtable。但它的key-value对
的有序性,使得在查找方面有优势
3.LinkedHashMap底层因采用链表来维护有序性,因此它的性能不如HashMap。但它能保证有序性
4.EnumSet的实现性能最好,底层是基于数组实现的,但key只能是枚举值