Map接口中的每个成员方法由一个关键字(key)和一个值(value)构成。Map接口不直接继承于Collection接口,因
为它包装的是一组成对的"键-值"对象的集合,而且在Map接口的集合中也不能有重复的key出现,因为每个键只能与
一个成员元素相对应。
Map接口定义了存储"键(key)——值(value)映射对"的方法。实现Map接口的类用来存储键值对。Map接口中包含
了一个keySet()方法,用于返回Map中所有key组成的Set集合。
Map接口的特点有:
1)Map接口提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储 的,能够实现根据key快速查找value。2)Map中的键值对以Entry类型的对象实例形式存在。键(key值)不可重复,value值可以。
3)每个键最多只能映射到一个值。4)Map接口提供了分别返回key值集合,value值集合以及Entry(键值对)集合的方法。
5)Map同样也支持泛型,形式如:Map
6)Map接口中存储的键—值对通过键来标识,所以键值不能重复,即同一个Map对象的任何两个key通过equals()
方法比较总是返回false。
Map接口中定义的方法有:
Map接口的主要有三个实现类,分别是:HashMap、TreeMap和HashTable。一般情况下,我们用的最多的是
HashMap,在Map中插入、删除和定位元素,HashMap是最好的选择。但如果您要按自然顺序或自定义顺序遍历
键,那么TreeMap会更好。如果需要输出的顺序和输入的相同。那么用HashMap的子类LinkedHashMap可以实现,
它还可以按读取顺序来排列。
Hashmap类是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访
问速度,遍历时,取得数据的顺序是完全随机的。HashMap最多只允许一条记录的键为Null;允许多条记录的值为
Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要
同步,可以用Collections集合类的synchronizedMap()方法使HashMap类具有同步的能力。
由于HashMap里的不能重复,所以HashMap里最多只有一对key-value值为null,但可以有无数多项key-value对
的value为null。
HashMap重写了toString()方法方法总是返回如下格式的字符串:{key1 = value1,key2 = value2...}
HashMap判断两个key相等的标准是:两个key通过equasl()方法比较返回ture,两个key的hashCode值相等。
HashMap的特点:
1)HashMap是Map的一个重要实现类,也是最常用的,基于哈希表实现。
2)HashMap中的Entry对象是无序排列的。
3)Key值和value值都可以是null,但是一个HashMap只能有一个key值为null的映射(key值不可重复)。
HashMap实现类的方法:
实例:
import java.util.*;
public class TestHashMap {
public static void main(String[] args) {
Map hashMap = new HashMap();
Dog d1 = new Dog("red");
Dog d2 = new Dog("black");
Dog d3 = new Dog("white");
Dog d4 = new Dog("white");
hashMap.put(d1, 10);
hashMap.put(d2, 15);
hashMap.put(d3, 5);
hashMap.put(d4, 20);
//print size
System.out.println(hashMap.size());
//loop HashMap
for (Map.Entry entry : hashMap.entrySet()) {
System.out.println(entry.getKey().toString() + " - " + entry.getValue());
}
}
}
class Dog {
String color;
Dog(String c) {
color = c;
}
public String toString(){
return color + " dog";
}
}
运行结果:
注意看,我们错误地添加了两次"white dogs",但是HashMap接受了,这严格来说是没意义的,因为现在对"white
dogs"的数量产生了混淆。
修正后的 Dog 类如下所示:
class Dog {
String color;
Dog(String c) {
color = c;
}
public boolean equals(Object o) {
return ((Dog) o).color == this.color;
}
public int hashCode() {
return color.length();
}
public String toString(){
return color + " dog";
}
}
运行结果:
原因在于HashMap不运行两个相同的元素作为KEY。如果没有重写,使用的就会是Object类实现的hashCode()和
equals()方法,默认的 hashCode()方法实现对每个不同的对象返回不同的整数;默认的equals()方法只比较两个引用
是否指向同一个实际对象。
Map接口派生了一个SortedMap子接口,TreeMap为其实现类。类似TreeSet排序,TreeMap也是基于红黑树对
TreeMap中所有key进行排序,从而保证TreeMap中所有key-value对处于有序状态。TreeMap两种排序方法:
1)自然排序:TreeMap的所有key必须实现Comparable接口,而且所有key应该是同一个类的对象,否则将会抛出
ClassCastExcepiton异常。
2)定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中所有key进行排序。采用定
制排序时不要求Map的key实现Comparable接口。
TreeMap中判断两个key相等的标准也是两个key通过equals()方法比较返回true,而通过compareTo()方法返回
0,TreeMap即认为这两个key是相等的。
如果使用自定义的类作为TreeMap的key,应重新该类的equals(0方法和compareTo()方法时应有一致的返回结
果:即两个key通过equals()方法比较返回true时,它们通过compareTo()方法比较应该返回0。如果equals()方法与
compareTo()方法的返回结果不一致,要么该TreeMap与Map接口的规则有出入(当equals()方法比较返回true,但
CompareTo()方法比较不返回0时),要么TreeMap处理起来性能有所下降(当compareTo()方法比较返回0,当
equals()方法比较不返回true时)。
TreeMap实现了的方法:
实例:
import java.util.*;
public class TestTreeMap {
public static void main(String[] args) {
Dog d1 = new Dog("red");
Dog d2 = new Dog("black");
Dog d3 = new Dog("white");
Dog d4 = new Dog("white");
Map treeMap = new TreeMap();
treeMap.put(d1, 10);
treeMap.put(d2, 15);
treeMap.put(d3, 5);
treeMap.put(d4, 20);
for (Map.Entry entry : treeMap.entrySet()) {
System.out.println(entry.getKey() + " - " + entry.getValue());
}
}
}
class Dog {
String color;
Dog(String c) {
color = c;
}
public boolean equals(Object o) {
return ((Dog) o).color == this.color;
}
public int hashCode() {
return color.length();
}
public String toString(){
return color + " dog";
}
}
运行结果:
既然TreeMap是按key排序的,那么key对象就必须可以和另一个对象作比较,因此必须实现Comparable接口。当
然,你也可以使用String对象作为key,因为String类已经实现了Comparable接口。
下面,我们修改Dog类的代码,使其实现Comparable接口:
import java.util.*;
public class TestTreeMap {
public static void main(String[] args) {
Dog d1 = new Dog("red", 30);
Dog d2 = new Dog("black", 20);
Dog d3 = new Dog("white", 10);
Dog d4 = new Dog("white", 10);
Map treeMap = new TreeMap();
treeMap.put(d1, 10);
treeMap.put(d2, 15);
treeMap.put(d3, 5);
treeMap.put(d4, 20);
for (Map.Entry entry : treeMap.entrySet()) {
System.out.println(entry.getKey() + " - " + entry.getValue());
}
}
}
class Dog implements Comparable{
String color;
int size;
Dog(String c, int s) {
color = c;
size = s;
}
public String toString(){
return color + " dog";
}
@Override
public int compareTo(Dog o) {
return o.size - this.size;
}
}
运行结果:
这就是根据key对象排序的结果,此处我们使用了size(尺寸)来比较dog.如果我们把"Dog d4 = new Dog("white"
,10);"这一行代码替换为"Dog d4 = new Dog("white", 40);"那么,执行后的结果为:
原因是TreeMap使用compareTo()方法来比较key对象,不同的size就被认为是不同的dog。
关于Map接口及其实现类的东西就说这么多。