Java集合框架(下)之Map的containsKey()與containsValue()方法
在閱讀本文之前,要確保已經閱讀Java集合框架(上)與Java集合框架(中)。本文講述Map集合的containsKey()與containsValue()的用法與注意事項。
在MapTest.java中新增testContainsKeyOrValue()方法:
public void testContainsKeyOrValue(){
Scanner sc = new Scanner(System.in);
//Key
System.out.println("請輸入要查詢的學生id:");
String id = sc.next();
System.out.println("你輸入的學生id為:" +id+",在學生對映表中是否存在"+
students.containsKey(id));
if(students.containsKey(id)){
System.out.println("對應的學生為:"+students.get(id).name);
}
//Value
System.out.println("請輸入要查詢的學生姓名:");
String name = sc.next();
if(students.containsValue(new Student(null,name))){
System.out.println("在學生對映表中,確實包含學生:"+name);
}
else{
System.out.println("在學生對映表中不存在這個學生");
}
}
執行結果:
請輸入學生id:
1
輸入學生姓名以建立學生:
小明
成功新增學生:小明
請輸入學生id:
2
輸入學生姓名以建立學生:
哈哈
成功新增學生:哈哈
請輸入學生id:
3
輸入學生姓名以建立學生:
極客咯
成功新增學生:極客咯
總共有3個學生
學生:小明
學生:哈哈
學生:極客咯
請輸入要查詢的學生id:
2
你輸入的學生id為:2,在學生對映表中是否存在true
對應的學生為:哈哈
請輸入要查詢的學生姓名:
小明
在學生對映表中不存在這個學生
結果分析:
可以看到,通過containsKey(Object key)方法比較的結果返回true,是我們想要的結果。通過containsValue(Object value)方法比較的結果返回是false,但是我們確實是有一個名字叫小明的學生啊。為什麼呢?
檢視containsKey(Object key)和containsValue(Object value)的API說明:
- containsKey(Object key):Returns true if this map contains a mapping for the specified key. More formally, returns true if and only if this map contains a mapping for a key k such that (key==null ? k==null : key.equals(k)). (There can be at most one such mapping.)
- containsValue(Object value):Returns true if this map maps one or more keys to the specified value. More formally, returns true if and only if this map contains at least one mapping to a value v such that (value==null ? v==null : value.equals(v)). This operation will probably require time linear in the map size for most implementations of the Map interface.
- 可以看到,都呼叫了equals()方法進行比較!因此可以回答為什麼了,我們的Key是String型別的,String型別的equals()比較的是字串本身的內容,所以我們根據鍵去查詢學生的結果是true。而Value是Student型別的,equals()是直接用==實現的,==比較的是物件的引用地址,當然返回結果是false(參考equals()與==的區別與實際應用)。所以,要在Map中通過學生的名字判斷是否包含該學生,需要重寫equals()方法。
在Student.java中重寫equals()方法:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
再次執行,得到執行結果:
請輸入學生id:
1
輸入學生姓名以建立學生:
小明
成功新增學生:小明
請輸入學生id:
2
輸入學生姓名以建立學生:
哈哈
成功新增學生:哈哈
請輸入學生id:
3
輸入學生姓名以建立學生:
極客咯
成功新增學生:極客咯
總共有3個學生
學生:小明
學生:哈哈
學生:極客咯
請輸入要查詢的學生id:
2
你輸入的學生id為:2,在學生對映表中是否存在true
對應的學生為:哈哈
請輸入要查詢的學生姓名:
小明
在學生對映表中,確實包含學生:小明
結果分析:
通過重寫equals()實現了Map中通過學生姓名查詢學生物件(containsValue()方法)。