java.util.Map学习笔记

来源:互联网 发布:linux dma使用 编辑:程序博客网 时间:2024/05/17 23:49

概述


Map主要用于保存key-value对。在一个Map对象中,不允许存在相同的key,并且每个key最多可以映射到一个值(value)。Map接口主要用于替换抽象类java.util.Dictionary

Map接口中提供了3种集合视图,分别为:Map对象中所有key的集合,Map对象中所有value的集合,Map对象中所有实例(entry)的集合。Map中实例的顺序与map对象的迭代器遍历Map实例集合的顺序相同。而在一些Map接口的实现中,例如:TreeMap,对于Map对象中的实例提供了排序算法,而HashMap则没有提供类似的机制。

java.util.Set接口类似,由于Map接口中对于key要求的唯一性,最好不要将一个易变对象作为Map的key,因为在修改过程中导致的两个key相等的情况,Map并不能很好的检测到,可能影响到map针对这个key的行为。但是我们可以将这个可变对象作为map的值存在,因为对象的修改并不会影响到map的其它操作。

在Map接口的实现过程中,一般需要提供两个构造方法:默认无参构造方法,带有Map参数的构造方法。实际上,第二中构造方法的形式允许用户去拷贝任何map对象,生成一个等价的、拥有特定类型的map对象。该接口中也定义了一些可选的方法,当被调用的map对象不支持这些方法时,将抛出UnsupportedOperationException异常。当用户调用的方法不会对map对象产生任何修改时,也可以选择抛出异常(非强制性抛出)。

一些map接口的实现对于key和value均存在一些限制。如:有些实现不允许将null作为key或者value,而有些实现则规定了其合法的key和value的类型。当试图插入一个非法的key或者value时,则会抛出非检查(unchecked)异常,一般情况下是NullPointerException或者ClassCastException。当检索一个非法的key或者value时,则可能抛出异常或者姐放回false。

许多集合框架中的方法均基于equals方法实现。例如,containsKey(Object key)声明:当map对象存在一个key:k 满足条件(key==null ? k==null : key.equals(k))时,则返回true,否则返回false。但这并不代表调用该方法时,对于一个非空的key都一定会调用key.equals(k)。在map接口的实现过程中,可以做一定的优化,如:首先判断二者的哈希值是否相等,如果相等,在调用equals,否则可以直接返回false。也就是说在实现集合接口的方法时,可以适当利用底层Object提供的方法提升算法效率。

map定义的基于递归调用的操作在直接自引用或者间接自引用的情况下,可能失败。这些方法包括:lone(), equals(), hashCode() 和 toString()。在实现map接口的过程中,可以对自引用进行校验,但是目前的实现并没有提供这种机制。


内部接口说明(Entry)


类说明

Map中记录实例,每个实例是一个键-值对(key-value pair)。当调用方法Map.entrySet时,则会返回一个Entry的集合。调用该集合的迭代器是唯一一个获取Map中记录的方式。并且这些记录(Entry)对象与遍历该集合的迭代器有效期相同。也就是说:当在迭代该集合元素时,Map中的记录发生了结构性修改,那么在修改之前生成的迭代器可能获取到脏数据。

方法介绍

K getKey();

返回当前键-值对中的键。

V getValue();

返回当前键-值对中的值。如果该对应关系在调用该方法时,被其它线程使用迭代器的remove方法删除该实例,那么调用该方法可能返回脏数据。

V setValue(V value);

将当前实例中的值用指定的值代替(可选操作)。同理,当调用该方法时,被其它线程使用迭代器的remove方法删除该实例,那么调用该方法可能返回脏数据。

boolean equals(Object o);

判断两条记录是否相等,当两者相等时,返回true,否则返回false。

假设存在两条记录e1e2,当满足如下条件时,则代表两者相等:

e1.getKey()==null ? e2.getKey()==null : e1.getKey().equals(e2.getKey())且e1.getValue()==null ? e2.getValue()==null : e1.getValue().equals(e2.getValue())
int hashCode()

返回当前记录的哈希值。哈希值的计算方法为:key的哈希值 ^ value的哈希值,null元素对应的哈希值为0:

(e.getKey()==null   ? 0 : e.getKey().hashCode()) ^(e.getValue()==null ? 0 : e.getValue().hashCode())

方法说明


int size();

返回当前map对象中包含key-value对的数目。

boolean isEmpty();

判断当前map对象是否包含key-value对,若包含,返回true,否则返回false。

boolean containsKey(Object key);

当map对象中包含一个与key相等的键时,返回true,否则返回false。判断相等的条件为:(key==null ? k==null : key.equals(k))(在一个map对象中,至多存在一个满足这个条件的key)。

boolean containsValue(Object value);

判断当前的map对象是否包含与value相等的值,其判定条件为:value==null ? v==null : value.equals(v)。这个操作在大多数的map实现中,其执行时间与map对象的大小呈线性关系。

V get(Object key);

返回map中键值key对应的值。当map中不包含key时,返回null(在每个map中,至多存在一个满足这种条件的值)。如果当前的map对象允许null作为值,那么返回的null将不能证明对应的key在map对象中不存在,可能在map对象中,key对应的值就是null。在这种情况下,可能需要调用containsKey来区分这两种情况。

V put(K key, V value);

在map对象中,创建并保存key与value的对应关系(可选操作)。如果当前map中已经存在了一个键为key的键值对,则将这个键对应的值用value替换。对于一个map对象m,当且仅当调用m.containsKey(k)返回true时,才认为m中存在键为k的键值对。当存在该键时,返回对应的旧值,否则返回null。

V remove(Object key);

删除map中键值为key的键值对(可选操作)。当map对象中包含key时,返回其对应的值,否则返回null。当该map允许null作为值时,则返回null并不一定代表map中不存在键为key的键值对。在调用该方法后,该map对象将不再包含任何一个键为key的键值对。

void putAll(Map<? extends K, ? extends V> m);

将m中所有的键值对复制到当前map对象中(可选操作)。这个方法的执行结果相当于遍历m中多有的键值对k-v,并对每个键值对调用put(k, v)方法。当在执行本方法执行过程中,m发生并发结构修改,则该方法将产生不确定的执行结果。

void clear();

删除该map对象中所有的key-value对。在调用该方法后,该map对象将不包含任何实例。

Set<K> keySet();

将当前map对象中包含的所有的key生成一个不包含重复元素的集合(Set)。这个集合由当前map对象进行维护,因此对当前map对象进行的操作将会直接反映到该集合中,反之亦然。如果迭代这个key集合时,map对象发生了修改(除持有key迭代器的线程外),那么将产生不确定的迭代结果。这个集合允许通过Iterator.remove, Set.remove, removeAll, retainAll, 和 clear 进行删除元素操作。但是并不支持add和addAll操作。

Collection<V> values();

将当前map对象中包含的所有的value,生成一个集合(Collection,可能包含重复元素)。其也由map对象进行维护,其修改操作会互相影响。

Set<Map.Entry<K, V>> entrySet();

返回当前map对象中包含的所有的key-value对,并生成Map.Entry的集合。

boolean equals(Object o);

判断两个Map对象是否相等。因为Map对象代表一种对应关系,因此当两个Map对象包含相同的对应关系时,则认为两者相等。
假设存在两个map对象m1m2,当m1.entrySet().equals(m2.entrySet())时,则认为两者相等。

int hashCode();

返回当前map对象的哈希值。一个Map对象的哈希值是当前对象中包含的所有的哈希值的和。


0 0