http://blog.csdn.net/zccst/article/details/5096467
1. Map接口概述
java.util.Map接口描述了映射结构,Map接口允许以键集、值集合或键-值映射关系集的形式查看某个映射的内容。
Java 自带了各种 Map 类。 这些 Map 类可归为三种类型:
1.通用 Map,用于在应用程序中管理映射,通常在 java.util 程序包中实现
* HashMap
* Hashtable
* Properties
* LinkedHashMap
* IdentityHashMap
* TreeMap
* WeakHashMap
* ConcurrentHashMap
2.专用 Map,您通常不必亲自创建此类 Map,而是通过某些其他类对其进行访问
* java.util.jar.Attributes
* javax.print.attribute.standard.PrinterStateReasons
* java.security.Provider
* java.awt.RenderingHints
* javax.swing.UIDefaults
3.一个用于帮助实现您自己的Map 类的抽象类
* AbstractMap
接口中的重要方法如下:
1, 覆盖的方法
equals(Object o) //比较指定对象与此 Map 的等价性
hashCode() //返回此 Map 的哈希码
2, Map更新方法,可以更改Map的内容。
put(Object key, Object value) //添加键值对,若键已存在,则覆盖旧值。
putAll(Map t) //将指定 Map 中的所有映射复制到此 map
remove(Object key) //从 Map 中删除与key关联的value
clear() //从 Map 中删除所有映射
3, 返回视图的Map方法:使用这些方法返回的对象,你可以遍历和删除Map的元素。
Set keySet() //返回 Map 中所包含键的 Set 视图。
//删除 Set 中的key元素还将删除 Map 中相应的映射(键和值)
Collection values() //返回 map 中所包含值的 Collection 视图。
//删除 Collection 中的value元素还将删除 Map 中相应的映射(键和值)
Set entrySet() //返回 Map 中所包含映射的 Set 视图(键值对)。
Set 中的每个元素都是一个 Map.Entry 对象,可以使用 getKey() 和 getValue() 方法(还有一个 setValue() 方法)访问Map.Entry 对象的键元素和值元素
关于Map.Entry接口
Map的entrySet()方法返回一个实现Map.Entry接口的对象集合。集合中每个对象都是底层Map中一个特定的键/值对。通过这个集合的迭代器,您可以获得每一个条目(唯一获取方式)的键或值并对值进行更改。
(1) Object getKey(): 返回条目的关键字
(2) ObjectgetValue(): 返回条目的值
(3) ObjectsetValue(Object value): 将相关映像中的值改为value,并且返回旧值
当条目通过迭代器返回后,除非是迭代器自身的remove()方法或者迭代器返回的条目的setValue()方法,其余对源Map外部的修改都会导致此条目集变得无效,同时产生条目行为未定义。
4, Map访问和测试方法:这些方法检索有关Map内容的信息但不更改Map内容。
get(Object key) //返回与指定键关联的值及此对象,若无,返回null。
boolean containsKey(Objectkey) //如果 Map 包含指定键的映射,则返回true
boolean containsValue(Objectvalue) //若此 Map 将一个或多个键映射到指定值,返回 true
isEmpty() //如果 Map 不包含键-值映射,则返回 true
int size() //返回 Map 中的键-值映射的数目
几乎所有通用 Map 都使用哈希映射。这是一种将元素映射到数组的非常简单的机制,您应了解哈希映射的工作原理,以便充分利用 Map。
哈希映射结构由一个存储元素的内部数组组成。由于内部采用数组存储,因此必然存在一个用于确定任意键访问数组的索引机制。实际上,该机制需要提供一个小于数组大小的整数索引值(即余数)。该机制称作哈希函数。 在 Java 基于哈希的 Map 中,哈希函数将对象转换为一个适合内部数组的整数。 您不必为寻找一个易于使用的哈希函数而大伤脑筋: 每个对象都包含一个返回整数值的 hashCode() 方法。 要将该值映射到数组,只需将其转换为一个正值,然后在将该值除以数组大小后取余数即可。
哈希函数将任意对象映射到一个数组位置,但如果两个不同的键映射到相同的位置,情况将会如何?这是一种必然发生的情况。 在哈希映射的术语中,这称作冲突。 Map 处理这些冲突的方法是在索引位置处插入一个链接列表,并简单地将元素添加到此链接列表。
图示:
2. 接口实现类HashMap
java.util.HashMap类实现了java.util.Map接口。
HashMap结构不保证其中元素(映射信息)的先后顺序,并且允许使用null值和null键。当集合中不存在当前检索的键所对应的映射值是,HashMap的get()方法会返回空值null,而不会运行出错。
影响HashMap性能的两个参数:
1, 初始容量(initial Capacity)。
2, 加载因子(Load Factor)
常用方法:
(1) HashMap() //构建一个空的哈希映像
(2)HashMap(Map m) //构建一个哈希映像,并且添加映像m的所有映射
(3)HashMap(int initialCapacity) //构建一个拥有特定容量的空的哈希映像
(4)HashMap(int initialCapacity, float loadFactor) //构建一个拥有特定容量和加载因子的空的哈希映像
例如:
public class Person implementsjava.lang.Comparable{
privatefinal int id;
privateString name;
privateint age;
publicPerson(int id,String name,int age){
this.id= id;
this.name= name;
this.age= age;
}
publicint getId(){
returnid;
}
publicvoid setName(String name){
this.name= name;
}
publicString getName(){
returnname;
}
publicvoid setAge(int age){
this.age= age;
}
publicint getAge(){
returnage;
}
publicString toString(){
return"Id: " + id + "/tName: " + name + "/tAge: " +age;
}
@Override
publicint compareTo(Object o){
Personp = (Person)o;
returnthis.id - p.id;
}
@Override
publicboolean equals(Object o){
booleanflag = false;
if(oinstanceof Person){
if(this.id== ((Person)o).id)
flag= true;
}
returnfalse;
}
}
import java.util.Set;
import java.util.HashMap;
import java.util.Collection;
import java.util.Iterator;
public class TestHashMap{
publicstatic void main(String[] args) {
HashMaphm = new HashMap();
hm.put(newInteger(1003),new Person(1003,"张三",15));
hm.put(newInteger(1008),new Person(1008,"李四",25));
hm.put(1015,newPerson(1015,"王五",73)); //自动封装
hm.put(1001,newPerson(1001,"赵六",49));
System.out.println("----检索单个元素----");
Personp = (Person)hm.get(1008);
System.out.println(p);
System.out.println("----遍历所有/"键/"(元素名)----");
Setnames = hm.keySet();
for(Objecto : names){
System.out.println(o);
}
System.out.println("----遍历所有/"值/"(元素值)----");
Collectionvalues = hm.values();
for(Objecto : values){
System.out.println(o);
}
}
}
输出结果:
----检索单个元素----
Id: 1008 Name: 李四 Age: 25
----遍历所有"键"(元素名)----
1001
1003
1008
1015
----遍历所有"值"(元素值)----
Id: 1001 Name: 赵六 Age: 49
Id: 1003 Name: 张三 Age: 15
Id: 1008 Name: 李四 Age: 25
Id: 1015 Name: 王五 Age: 73
3. 接口实现类Hashtable
java.util.Hashtable与HashMap作用基本相同,也实现了Map接口,采用哈希表的方式将“键”映射到相应的值来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
Hashtable与HashMap的差别:
1, Hashtable中元素的键和值均不允许为null,而HashMap可以
2, Hashtable是同步的,即线程安全的,效率相对要低一些,适合在多线程环境下使用;而HashMap是不同步的,效率相对高一些,提倡在单线程环境下使用。
相同点是:Hashtable与HashMap的用法格式是完全相同的。
Hashtable类的使用:
为了把对象保存到哈希表中,必须为每一对象分配一关键字。关键字可以为任意对象,但必须实现了hashCode()和equals()方法。
Hash_1.put(“one”, new Integer(1));
Hash_1.put(“two”, new Integer(2));
Hash_1.put(“three”, new Integer(3));
把对象从哈希表删除,须使用remove()方法。
Hash_1.remove(“two”); //对象Integer(2)将从哈希表中删除,同时返回这个被删除的对象。如果指定的关键字不存在,remove()返回null。
使用哈希表类的get()和containKey()访问方法可以直接查找关键字。
Integer n = (Integer) Hash_1.get(“three”);
If (n != null){System.out.println(“three=”+ n);} //如果查找的关键字不存在,get返回null
例如:MyKey.java、Person.java、TestTreeMap.java
(1) MyKey.java
public class MyKey implements Comparable{
privatefinal int id;
publicMyKey(int id){
this.id= id;
}
publicint getId(){
returnid;
}
@Override
publicint compareTo(Object o){
returnthis.id - ((MyKey)o).id;
}
@Override
publicboolean equals(Object o){
return(o instanceof MyKey) && (this.id == ((MyKey)o).id);
}
@Override
publicint hashCode(){
returnnew Integer(id).hashCode();
}
}
(2) Person.java
public class Person{
privateString name;
privateint age;
publicPerson(String name,int age){
this.name= name;
this.age= age;
}
publicvoid setName(String name){
this.name= name;
}
publicString getName(){
returnname;
}
publicvoid setAge(int age){
this.age= age;
}
publicint getAge(){
returnage;
}
publicString toString(){
return"Name: " + name + "/tAge: " + age;
}
}
(3) TestTreeMap.java
import java.util.Set;
import java.util.TreeMap;
import java.util.Iterator;
public class TestTreeMap{
publicstatic void main(String[] args) {
TreeMaphm = new TreeMap();
hm.put(newMyKey(1003),new Person("Tom",15));
hm.put(newMyKey(1008),new Person("Billy",25));
hm.put(newMyKey(1005),new Person("Kity",73));
hm.put(newMyKey(1001),new Person("Nancy",49));
System.out.println("----检索单个元素----");
Personp = (Person)hm.get(new MyKey(1008));
System.out.println(p);
System.out.println("----遍历所有元素----");
Setnames = hm.keySet();
Iteratorit = names.iterator();
while(it.hasNext()){
MyKeykey = (MyKey)it.next();
Personvalue = (Person)hm.get(key);
System.out.println(key.getId()+ "/t" + value);
}
}
}
输出结果:
----检索单个元素----
Name: Billy Age: 25
----遍历所有元素----
1001 Name: Nancy Age: 49
1003 Name: Tom Age: 15
1005 Name: Kity Age: 73
1008 Name:Billy Age: 25