Map
13.7 Map接口
13.7.1 Map接口简介
Collection、Set、List接口都属于单值的操作,即每次只能操作一个对象。
Map每次操作的是一对对象,即二元偶对象,Map中的每个元素都使用 key--->value 的形式存储在集合中
Map接口的定义:
public interface Map<k,v>
Map 上也应用了泛型,必须同时设置好 key 或 value 的类型,在Map中每一对 key--->value都表示一个值。
13.7.2 Map.Entry 接口简介
Map.Entry 是 Map 内部定义的一个接口,专门用来保存 key-->value 的内容。
Map.Entry 定义如下:
public static interface Map.Entry <k,v>
Map.Entry 是使用 static 关键字声明的内部接口,此接口可以由外部通过“外部类.内部类”的形式直接调用
在 Map 操作中,所有的内容都是通过 key-->value 的形式保存数据的,那么对于集合来讲,实际上是将 key--->value 的数据保存在了 Map.Entry 的实例之中,再在 Map 集合中插入的是一个 Map.Entry 的实例化对象
Map与Map.Entry
Map.Entry 接口提供了如下方法:
public boolean equals(Object o) 对象比较
public K getKey( ) 取得 key
public V getValue( ) 取得 value
public int hashCode( ) 返回哈希码
public V setValue(V value ) 设置 value的值
13.7.3 Map 接口的常用子类
要使用Map接口也必须依靠其子类实例化。Map 接口中常用的子类如下
HashMap:无序存放的,新的操作类,key不允许重复
Hashtable:无序存放的,旧的操作类,key不允许重复
TreeMap:可以排序的Map集合,按集合中的 key排序,key不允许重复
WeakHashMap:弱引用的Map集合,当集合中的某些内容不再使用时清除掉无用的数据,使用 gc 进行回收
IdentityHashMap:key 可以重复的 Map 集合
1.新的子类:HashMap
HashMap 本身是 Map 的子类,直接使用此类为 Map接口实例化即可。
HashMap 类的定义如下:
public class HashMap<k,v>
extends AbstractMap<k,v>
implements Map<k,v>,Cloneable,Serializable
HashMap 是 AbstractMap类的子类。AbstractMap 类的定义如下:
public abstract class AbstractMap<k,v>
extends Object
implements Map<k,v>
2.旧的子类:Hashtable
Hashtable 也是 Map 中的一个子类,与 Vector类的推出时间一样,都属于旧的操作类,使用上也和之前没有太大区别。
HashMap 与 Hashtable 的区别
HashMap:JDK1.2之后推出,属于新的操作类;采用异步处理方式,性能更高;属于非线程安全的操作类。
Hashtable:JDK1.0时推出,属于旧的操作类;采用同步处理方式,性能较低;属于线程安全的操作类。
3.排序的子类:TreeMap
HashMap 和 Hashtable 两个子类在存放数据时并没有对其进行排序,而 TreeMap 的主要功能是按 key 排序。
3.弱引用类WeakHashMap
前面几种 Map 子类中的数据都是使用强引用保存的,即里面的内容不管是否使用都始终在集合中保留,如果希望集合自动清理暂时不用的数据就需要使用 WeakHashMap类。
这样当进行垃圾收集时会释放掉集合中的垃圾信息,WeakHashMap 的定义如下:
public class weakHashMap<k,v>
extends AbstractMap<k,v>
implements Map<k,v>
对象的引用强度说明:
从 JDK1.2 版本开始,Java把对象的引用分为4种级别,从而使程序能更加灵活地控制对象地声明周期。这4种级别由高到低依次为:强引用、软引用、弱引用和虚引用
强引用:当内存不足时,JVM宁可出现 OutOfMemeryError 错误而使程序停止,也不会回收此对象来释放空间。
软引用:当内存不足时,会回收这些对象的内存,用来实现内存敏感的高速缓存。
弱引用:无论内存是否紧张,被垃圾回收器发现立即回收。
虚引用:和没有任何引用一样。
13.7.4 Map 接口使用注意事项
1.注意事项一:不能直接使用迭代输出 Map 中的全部内容
对于Map接口来说,其本身是不能直接使用迭代(Iterator、foreach)进行输出的,因为Map中的每个位置存放的是一对值(key-->value),而 Iterator 中每次只能找到一个值。
所以,如果非要使用迭代进行输出,则必须按照以下步骤完成(以 Iterator 输出方法为例)
(1)将 Map 的实例通过 entrySet() 方法变为Set 接口对象
(2)通过 Set 接口实例为 Iterator 实例化
(3)通过 Iterator 迭代输出,每个内容都是 Map.Entry 的对象
(4)通过 Map.Entry 进行 key-->value 的分离
前面提过,Map中的每对数据都是通过 Map.Entry 保存的,所以如果最终要进行输出也应该使用 Map.Entry 完成。
Map集合的内容在开发中基本上作为查询的应用较多,全部输出的操作较少。而Collection接口在开发中的主要作用就是用来传递内容及输出的。