集合 Map

和 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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章