一、Map的集合框架
二、Map接口
將鍵映射到值的對象。map不能包含重複的鍵;每個鍵可以映射到最多一個值。該接口取代了Dictionary類,Dictionary是一個完全抽象的類而不是接口。Map接口提供三個集合視圖,允許將映射內容視爲一組鍵、值集合或者是鍵值映射集合。map的順序被定義爲地圖集合視圖上的迭代器返回其元素的順序。一些map實現,對其順序做出特定的保證,如TreeMap類;其他的則不需要,如HashMap類。
public interface Map<K,V> {
// Query Operations
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
V put(K key, V value);
V remove(Object key);
void putAll(Map<? extends K, ? extends V> m);
void clear();
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
//Map是基於鏈表操作的,而每個元素存儲的就是Entry。Map.entrySet方法返回地圖的集合視圖,其元素屬於此類。 獲取對映射條目的引用的唯一方法是從該集合視圖的迭代器。 這些Map.Entry對象僅在迭代期間有效; 更正式地,如果在迭代器返回條目之後修改了背景映射,則映射條目的行爲是未定義的,除了通過映射條目上的setValue操作。
interface Entry<K,V> {
//返回與此條目相對應的鍵。
K getKey();
//返回與該條目對應的值。
V getValue();
//用指定的值替換與該條目相對應的值(可選操作)。
V setValue(V value);
//將指定的對象與此條目進行比較以獲得相等性。
boolean equals(Object o);
//返回此映射條目的哈希碼值
int hashCode();
//返回一個比較器,它按鍵的自然順序對Map.Entry進行比較。JDK1.8
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getKey().compareTo(c2.getKey());
}
//返回一個比較器,以比較Map.Entry的自然順序的值。JDK1.8
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getValue().compareTo(c2.getValue());
}
//返回一個比較器,它使用給定的比較器比較Map.Entry的鍵。JDK1.8
public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
Objects.requireNonNull(cmp);
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
}
//返回一個比較器,它使用給定的比較器比較Map.Entry的值。JDK1.8
public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
Objects.requireNonNull(cmp);
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
}
}
boolean equals(Object o);
int hashCode();
//返回指定鍵映射到的值,如果此映射不包含鍵的映射,則返回defaultValue。JDK1.8
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key)) ? v : defaultValue;
}
//對此映射中的每個條目執行給定的操作,直到所有條目都被處理或操作引發異常。JDK1.8
default void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}
//將每個條目的值替換爲對該條目調用給定函數的結果,直到所有條目都被處理或該函數拋出異常。
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Objects.requireNonNull(function);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
throw new ConcurrentModificationException(ise);
}
v = function.apply(k, v);
try {
entry.setValue(v);
} catch(IllegalStateException ise) {
throw new ConcurrentModificationException(ise);
}
}
}
//如果指定的鍵還沒有與值相關聯(或映射到null)將其與給定值相關聯並返回null,否則返回當前值。
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
v = put(key, value);
}
return v;
}
//只有當目標映射到指定的值時,才能刪除指定鍵的條目。
default boolean remove(Object key, Object value) {
Object curValue = get(key);
if (!Objects.equals(curValue, value) ||
(curValue == null && !containsKey(key))) {
return false;
}
remove(key);
return true;
}
//僅噹噹前映射到指定的值時,才能替換指定鍵的條目。
default boolean replace(K key, V oldValue, V newValue) {
Object curValue = get(key);
if (!Objects.equals(curValue, oldValue) ||
(curValue == null && !containsKey(key))) {
return false;
}
put(key, newValue);
return true;
}
//只有當目標映射到某個值時,才能替換指定鍵的條目。
default V replace(K key, V value) {
V curValue;
if (((curValue = get(key)) != null) || containsKey(key)) {
curValue = put(key, value);
}
return curValue;
}
//如果指定的鍵尚未與值相關聯(或映射到null),則嘗試使用給定的映射函數計算其值,並將其輸入到此映射中,除非爲null。
default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v;
if ((v = get(key)) == null) {
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
put(key, newValue);
return newValue;
}
}
return v;
}
//如果指定的鍵的值存在且非空,則嘗試計算給定鍵的新映射及其當前映射的值。
default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue;
if ((oldValue = get(key)) != null) {
V newValue = remappingFunction.apply(key, oldValue);
if (newValue != null) {
put(key, newValue);
return newValue;
} else {
remove(key);
return null;
}
} else {
return null;
}
}
//嘗試計算指定密鑰及其當前映射值的映射(如果沒有當前映射,則爲null)。
default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue = get(key);
V newValue = remappingFunction.apply(key, oldValue);
if (newValue == null) {
// delete mapping
if (oldValue != null || containsKey(key)) {
// something to remove
remove(key);
return null;
} else {
// nothing to do. Leave things as they were.
return null;
}
} else {
// add or replace old mapping
put(key, newValue);
return newValue;
}
}
//如果指定的鍵尚未與值相關聯或與null相關聯,則將其與給定的非空值相關聯。
default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
V oldValue = get(key);
V newValue = (oldValue == null) ? value :
remappingFunction.apply(oldValue, value);
if(newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}
}