和 C++ STL 中的map很像,就是換了代碼
鍵-值對應
下面直接給出操作
操作
Map中不存在重複的key,因爲放入相同的key,只會把原有的key-value對應的value給替換掉
代碼 | 作用 |
---|---|
Object put(Object k, Object v) | 將指定的值與此映射中的指定鍵關聯 |
void putAll(Map m) | 從指定映射中將所有映射關係複製到此映射中 |
Object get(Object k) | 返回指定鍵所映射的值;如果此映射不包含該鍵的映射關係,則返回 null |
Object remove(Object k) | 如果存在一個鍵的映射關係,則將其從此映射中移除 |
int size( ) | 返回此映射中的鍵-值映射關係數 |
boolean isEmpty( ) | 如果此映射未包含鍵-值映射關係,則返回 true |
void clear( ) | 從此映射中移除所有映射關係 |
boolean containsKey(Object k) | 如果此映射包含指定鍵的映射關係,則返回 true |
boolean containsValue(Object v) | 如果此映射將一個或多個鍵映射到指定值,則返回 true |
boolean equals(Object obj) | 比較指定的對象與此映射是否相等 |
int hashCode( ) | 返回此映射的哈希碼值 |
Set entrySet( ) | 返回此映射中包含的映射關係的 Set 視圖 |
Set keySet( ) | 返回此映射中包含的鍵的 Set 視圖 |
Collection values( ) | 返回此映射中包含的值的 Collection 視圖 |
創建
最常用的實現類是HashMap
Map<String, Integer> map = new HashMap<>();
遍歷
遍歷Map時,不可假設輸出的key是有序的
即:hashmap內部無序
1、要遍歷key或value可以使用for each循環遍歷Map實例的keySet()方法返回的Set集合,它包含不重複的key的集合:
(比下一種快)
//遍歷keys
for (String key : map.keySet())
Integer value = map.get(key);
//遍歷values
for (Integer value : map.values())
System.out.println("Value = " + value);
2、同時遍歷key和value可以使用for each循環遍歷Map對象的entrySet()集合,它包含每一個key-value映射:
for (Map.Entry<String, Integer> entry : map.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
}
3、迭代器遍歷:
可以在過程中,調用iterator.remove()來刪除entries,效率同第一種
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<Integer, Integer> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
Map map = new HashMap();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
Integer key = (Integer)entry.getKey();
Integer value = (Integer)entry.getValue();
System.out.println("Key = " + key + ", Value = " + value);
}
TreeMap
如果想讓map有序,需要使用 TreeMap
String、Integer這些類已經實現了Comparable,所以不需要再寫,可以直接使用。
如果是自定義類,需要在創建時寫Comparable方法
class Person {
public String name;
public int score;
/...
}
Map<Person, Integer> map = new TreeMap<>(new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Map<Student, Integer> map = new TreeMap<>(new Comparator<Person>() {
if (p1.score == p2.score) {
return 0;
}
return p1.score > p2.score ? -1 : 1;
});
覆寫hashCode
-
要正確使用HashMap,作爲key的類必須正確覆寫equals()和hashCode()方法;
-
一個類如果覆寫了equals(),就必須覆寫hashCode(),並且覆寫規則是:
-
如果equals()返回true,則hashCode()返回值必須相等;
-
如果equals()返回false,則hashCode()返回值儘量不要相等。
-
實現hashCode()方法可以通過Objects.hashCode()輔助方法實現。
對應兩個實例a和b:
- 如果a和b相等,那麼a.equals(b)一定爲true,則a.hashCode()必須等於b.hashCode();
- 如果a和b不相等,那麼a.equals(b)一定爲false,則a.hashCode()和b.hashCode()儘量不要相等。
上述第一條規範是正確性,必須保證實現,否則HashMap不能正常工作。
而第二條如果儘量滿足,則可以保證查詢效率,因爲不同的對象,如果返回相同的hashCode(),會造成Map內部存儲衝突,使存取的效率下降。
如果兩個對象不相等,則兩個對象的hashCode()儘量不要相等。
public class Person {
String firstName;
String lastName;
int age;
int hashCode() {
return Objects.hash(firstName, lastName, age);
}
}