之前說的Set(HashSet、TreeSet)接口和List(ArrayList、Vector、LinkedList)接口都是對單值別的操作,即每次只能操作一個對象。
Map接口與他們不同的是每次操作一對對象,Map中每個元素都使用“key----->value”的形式存儲在集合中。
public interface Map<K,V>
1、Map.Entry接口
Map.Entry接口是Map內部定義的一個接口,專門用來保存key--->Value的內容,是static關鍵字聲明的內部接口。
public static interface Map.Entry<K,V>
我們知道,在Map接口的操作中,所用的內容都是通過key--->Value的形式保存數據的,那麼對於集合來講,實際上將“key---->value”的數據保存在了Map.Entry接口的實例後,再在Map集合中插入一個Map.Entry的實例化對象,如下圖所示:
一般在Map操作中(增加、取出數據)用戶不用關心Map.Entry,但是將Map中的數據全部輸出時必須使用Map.Entry,隨後介紹。
本節主要介紹常用的子類:
HashMap:無序存放,新的操作類,key不允許重複。
HashTable:無序存放,舊的操作類,key不允許重複。
TreeMap:可排序map集合,按集合中key排序,key不允許重複。
WeakHashMap:弱引用Map集合,集合中某些內容不再使用時清除,使用gc回收。
IndentityHashMap:key可以重複的map集合。
2、HashMap
(1)向集合中增加和取出內容
put(K key, V value);增加
get(Object K)根據key找到對應的內容value
public class HashMapDemo01 {
/**
* Map接口中使用put增加內容,使用get(Object Key)根據Key找到內容value
*/
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("1", "www.bupt.cn");
map.put("2", "www.baidu.cn");
map.put("3", "www.haha.cn");
String str = map.get("1");
System.out.println("取得的內容是:"+str);
}
}
輸出結果爲:
取得的內容是:www.bupt.cn
(2)判斷指定的key或value是否存在
contains(Object key);
contains(Object value);
public class HashMapDemo06 {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("1", "www.bupt.cn");
map.put("2", "www.baidu.com");
map.put("3", "www.haha.com");
if(map.containsKey("2")){
System.out.println("搜索的key存在");
}else{
System.out.println("搜索的key不存在");
}
if(map.containsValue("www.souhu.com")){
System.out.println("搜索的value存在");
}else{
System.out.println("搜索的value不存在");
}
}
}
輸出結果:
指定的key存在
指定的value不存在
(3)輸出全部的key
Map接口中提供了一個keySet()的方法,可以將一個Map中的全部key變成一個Set集合,一旦有了Set接口實例,就可以直接使用Iterator接口進行輸出。操作時注意接收的Set集合中指定的泛型要和Map中key的泛型類型一致。
public class HashMapDemo02 {
/**
* 輸出全部的Key
*/
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("1","www.bupt.cn");
map.put("2", "www.baidu.cn");
map.put("3", "www.haha.cn");
Set<String> keys = map.keySet();//得到全部的Key,放入set集合
Iterator<String> iter = keys.iterator();//實例化Iterator
System.out.print("全部的Key:");
while(iter.hasNext()){
String str = iter.next();
System.out.print(str+"、");
}
}
}
輸出結果:
全部的Key:1、2、3、
(4)輸出全部的value
使用values()方法,返回Collection類型。使用時同樣注意泛型的類型。
public class HashMapDemo03 {
/**
* 輸出全部的value
*/
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("1", "www.bupt.cn");
map.put("2", "www.baidu.com");
map.put("3", "www.haha.com");
Collection<String> coll = map.values();//得到全部的value,放入Collection
Iterator<String> iter = coll.iterator();//實例化Iterator
System.out.print("全部的value:");
while(iter.hasNext()){
String str = iter.next();
System.out.print(str+"、");
}
}
}
輸出結果:
全部的value:www.bupt.cn、www.baidu.com、www.haha.com、
2、HashTable
HashTable與vector類的推出時間一樣,都屬於舊的操作類,使用上沒有太大區別。
性能:HashMap異步處理,性能高;HashTable同步處理,性能低。
線程安全:HashMap非線程安全;HashTable線程安全。
空鍵:允許Key設置爲null;HashTable不允許將Key設置爲null,否則出現Null Pointer Exception異常
實際開發中HashMap類使用較多。
3、TreeMap
之前的HashMap、HashTable存放數據時並沒有對其進行排序。
TreeMap子類的主要特點:可以按Key排序。(數字、字母等)
注意:使用自定義類作爲key時,類需要實現Comparable接口,String類作爲key可以按key排序,因爲String類本身已經實現了Comparable接口。
4、IdentityHashMap:key可以重複的Map集合
以上介紹的Map操作中key的值是不能重複的,例如,HashMap操作時如果key重複則肯定會覆蓋之前的內容。
下面結合實例主要看一下Map集合輸出全部內容以及IdentityHashMap的使用
這裏的Key爲一個自己定義的類Person2
class Person2 implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Person2(){}
public Person2(String name, int age){
this.name = name;
this.age = age;
}
// 重寫equals,定義同一類型,並且屬性name和age全部相等則實例對象相等
public boolean equals(Object obj){
if(this == obj){
return true;
}
if(!(obj instanceof Person2)){
return false;
}
Person2 p = (Person2) obj;
if(this.name.equals(p.name)&&this.age == p.age){
return true;
}else{
return false;
}
}
// 重寫HashCode將對象的某些信息映射成一個數值---散列值
public int hashCode(){
return this.name.hashCode()*this.age;//計算公式
}
// 重寫toString打印自己想要的格式,如果不重寫默認直接繼承Object類的toString 方法是獲取對象在內存中的值可能會亂碼
public String toString(){
return "姓名:"+this.name+";年齡:"+this.age;
}
}
public class IdentityHashMapDemo {
/**
* key 可以重複的IdentityHashMap類
*/
public static void main(String[] args) {
Map<Person2,String> map = new IdentityHashMap<Person2,String>();
map.put(new Person2("張三",30), "張三1");
map.put(new Person2("張三",30), "張三2");//增加內容,key重複
map.put(new Person2("李四",31), "李四");
// 輸出map集合全部內容:
// 聲明Set集合(存單值),每個內容都是Map.Entry的對象,Map接口通過entrySet()變爲set接口對象
Set<Map.Entry<Person2,String>> allSet = map.entrySet();
// 聲明並實例化Iterator對象
Iterator<Map.Entry<Person2,String>> iter = allSet.iterator();
// 迭代輸出
while(iter.hasNext()){
Map.Entry<Person2, String> m = iter.next();//每個對象都是Map.Entry實例
System.out.println(m.getKey()+"---->"+m.getValue());
}
}
}
輸出結果:
姓名:張三;年齡:30---->張三1
姓名:李四;年齡:31---->李四
姓名:張三;年齡:30---->張三2
由此可見IdentityHashMap中key允許重複,只要兩個對象的地址不相等即可。
5、Map接口使用需要注意的事項:
a、輸出Map全部內容的方法,先轉爲Set接口對象,再利用Set對象實例化Iterator,利用Iterator輸出每一個內容Map.Entry的對象
b、如果使用一個自定義的對象類表示Map中的key,則對象所在的類一定要重寫equals()和HashCode()方法。