标签:
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<K,V>。
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<Dog, Integer> hashMap = new HashMap<Dog, Integer>(); 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<Dog, Integer> 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<Dog, Integer> treeMap = new TreeMap<Dog, Integer>(); treeMap.put(d1, 10); treeMap.put(d2, 15); treeMap.put(d3, 5); treeMap.put(d4, 20); for (Map.Entry<Dog, Integer> 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<Dog, Integer> treeMap = new TreeMap<Dog, Integer>(); treeMap.put(d1, 10); treeMap.put(d2, 15); treeMap.put(d3, 5); treeMap.put(d4, 20); for (Map.Entry<Dog, Integer> entry : treeMap.entrySet()) { System.out.println(entry.getKey() + " - " + entry.getValue()); } } } class Dog implements Comparable<Dog>{ 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接口及其实现类的东西就说这么多。
JavaSE入门学习37:Java集合框架之Map接口及其实现类HashMap和TreeMap
标签:
原文地址:http://blog.csdn.net/erlian1992/article/details/51364207