Map接口中键和值一一映射. 可以通过键来获取值。
- 给定一个键和一个值,你可以将该值存储在一个Map对象。之后,你可以通过键来访问对应的值。
- 当访问的值不存在的时候,方法就会抛出一个NoSuchElementException异常.
- 当对象的类型和Map里元素类型不兼容的时候,就会抛出一个 ClassCastException异常。
- 当在不允许使用Null对象的Map中使用Null对象,会抛出一个NullPointerException 异常。
- 当尝试修改一个只读的Map时,会抛出一个UnsupportedOperationException异常。
序号 | 方法描述 |
---|---|
1 | void clear( ) 从此映射中移除所有映射关系(可选操作)。 |
2 | boolean containsKey(Object k) 如果此映射包含指定键的映射关系,则返回 true。 |
3 | boolean containsValue(Object v) 如果此映射将一个或多个键映射到指定值,则返回 true。 |
4 | Set entrySet( ) 返回此映射中包含的映射关系的 Set 视图。 |
5 | boolean equals(Object obj) 比较指定的对象与此映射是否相等。 |
6 | Object get(Object k) 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 |
7 | int hashCode( ) 返回此映射的哈希码值。 |
8 | boolean isEmpty( ) 如果此映射未包含键-值映射关系,则返回 true。 |
9 | Set keySet( ) 返回此映射中包含的键的 Set 视图。 |
10 | Object put(Object k, Object v) 将指定的值与此映射中的指定键关联(可选操作)。 |
11 | void putAll(Map m) 从指定映射中将所有映射关系复制到此映射中(可选操作)。 |
12 | Object remove(Object k) 如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 |
13 | int size( ) 返回此映射中的键-值映射关系数。 |
14 | Collection values( ) 返回此映射中包含的值的 Collection 视图。 |
实例
下面的例子来解释Map的功能
import java.util.*;
public class CollectionsDemo {
public static void main(String[] args) {
Map m1 = new HashMap();
m1.put("Zara", "8");
m1.put("Mahnaz", "31");
m1.put("Ayan", "12");
m1.put("Daisy", "14");
System.out.println();
System.out.println(" Map Elements");
System.out.print("\t" + m1);
}
}
以上实例编译运行结果如下:
Map Elements
{Mahnaz=31, Ayan=12, Daisy=14, Zara=8}
延伸:关于HashMap的进一步了解
介绍了HashMap处理冲突的方法,细讲了put()和get()方法,链接如下:
个人参考王道书上内容补充一下散列函数相关知识:
散列函数构造方法
在构造散列函数时,必须注意以下几点:
1) 散列函数的定义域必须包含全部需要存储的关键字,而值域的范围则依赖于散列表的大小或地址范围。
2) 散列函数计算出来的地址应该能等概率、均匀地分布在整个地址空间中,从而减少冲突的发生。
3) 散列函数应尽量简单,能够在较短的时间内计算出任一关键字对应的散列地址。
常用的散列函数
1) 直接定址法
字面意思,根据某个线性函数值计算出散列地址,如:
H(key) = a×key + b 优点:简单且不易冲突,适合关键字分布基本连续的情况。
缺点:若关键字分布不连续,空位较多,则会造成存储空间的浪费。
2) 除留余数法(最常用方法)
假定散列列表长m,取一个不大于m但最接近或等于m的质数p,利用以下公式把关键字转换成散列地址。散列函数为:
H(key) = key % p 关键:p的值需要仔细考虑,确保函数转换后等概率地映射到散列空间上的任意地址,从而减少冲突的可能性。
3) 数字分析法
设关键字是r进制数(如十进制数),而r个数码在各位上出现的频率不一定相同,可能在某些位上分布均匀一些,每种数码出现的机会相等;而在某些位上分布不均匀,只有某几种数码经常出现,此时应选取数码分布较为均匀的若干位作为散列地址。
适用场景:适合于已知的关键字集合。
举例:对于公司员工联系方式来说,手机号前几位基本固定几种组合,则可以去后几位作为关键字进行散列存储。
注意:若更换了关键字(如联系方式从手机号变成固定座机),则需要重新构造新的散列函数。
4) 平方取中法
顾名思义,去关键字的平方值的中间几位作为散列地址。具体取多少位要视实际情况而定。
适用场景:关键字的每位取值都不够均匀或均小于散列地址所需的位数时。
举例:1234² = 1,522,756,取中间三位227;2345² = 5,499,025,取中间三位990。
优点:得到的散列地址于关键字的每位都有关系,因此使得散列地址分布比较均匀。
5) 折叠法
将关键字分割成位数相同的几部分(最后一部分的位数可以短一些),然后去这几部分的叠加和作为散列地址。
适用场景:关键字位数很多,且关键字中的每位上数字分布大致均匀时。
举例:1,234,567,890,表长三位,可分为123 | 456 | 789 | 0,叠加求和123 + 456 + 789 + 0 = 1,368,取后三位得368。
处理冲突的方法
想让散列函数绝对地避免冲突是不可能的。为此,需要考虑在发生冲突时如何让关键字寻找下一个“空”的Hash地址。如下图所示:
注意:在开放地址的情况下,不能随便删除表中的已有元素,因为若删除元素,则会截断其他具有相同散列地址的元素的查找地址。因此,要删除一个元素时,可给它做一个逻辑标记,进行逻辑删除。但这样做的副作用是:执行多次删除操作之后,表面上看起来散列表很满,但实际上有许多位置未利用,因此需要定期维护散列表,要把删除标记的元素物理删除。