一、Map
public interface Map<K,V>
這是一個接口,Map的接口,K表示關鍵字的類型,V表示鍵值。
int size();//大小
boolean isEmpty();//是否爲空
boolean containsValue(Object value);//是否包含value
V get(Object key);//獲取鍵值爲key的value
V put(K key, V value);//添加
V remove(Object key);//移除鍵值爲key的map
void putAll(Map<? extends K, ? extends V> m);//添加一個映射
void clear();//移除所有的值
//Map-->這是一個轉換成set的方法
Set<K> keySet();//迭代的結果是相對無需,就是和插入順序無關 key值按照 1 2 3和 3 2 1的迭代結果都是一樣的。
二、Map的實現方法
1、HashMap
使用哈希表對鍵值進行存儲。存儲的位置和添加的順序無關,和HasCode計算的值有關。
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
構造函數:(初始,加載)
public HashMap(int initialCapacity, float loadFactor)
初始化的時候,會創建一個數組
new Entry[capacity];
允許最大長度(數組的數量+延伸的長度)。
threshold = (int)(capacity * loadFactor);
1、添加的源碼:
有下面可以看出,存儲的位置是有hash計算出來的。
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);//用來存取null 鍵值對
//hash值的計算方法
int hash = hash(key.hashCode());
//使用hash值找到存儲位置
int i = indexFor(hash, table.length);
//首先判斷是否存在,存在的話,就更新,並返回舊值
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
//判斷hash值---鍵值是否相等
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
//更新數量
modCount++;
//添加到數組裏
addEntry(hash, key, value, i);
return null;
}
get 方法就是找到hash位置,然後通過迭代找值
void addEntry(int hash, K key, V value, int bucketIndex) {
//獲取這個位置的值
Entry<K,V> e = table[bucketIndex];
//把原位置的值作爲新值的下一個,並替換掉原值
table[bucketIndex] = new Entry<>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
2、TreeMap
一、根據下面的繼承關係可以知道,TreeMap是間接實現了map方法。它具備更多的屬性。
有序的
public class TreeMap<K,V> extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
public interface NavigableMap<K,V> extends SortedMap<K,V>
public interface SortedMap<K,V> extends Map<K,V>
private final Entry<K,V> buildFromSorted(int level, int lo, int hi,
int redLevel,
Iterator it,
java.io.ObjectInputStream str,
V defaultVal)
throws java.io.IOException, ClassNotFoundException {
//紅黑樹進行排序
if (hi < lo) return null;
int mid = (lo + hi) >>> 1;
Entry<K,V> left = null;
if (lo < mid)
left = buildFromSorted(level+1, lo, mid - 1, redLevel,
it, str, defaultVal);
// extract key and/or value from iterator or stream
K key;
V value;
if (it != null) {
if (defaultVal==null) {
Map.Entry<K,V> entry = (Map.Entry<K,V>)it.next();
key = entry.getKey();
value = entry.getValue();
} else {
key = (K)it.next();
value = defaultVal;
}
} else { // use stream
key = (K) str.readObject();
value = (defaultVal != null ? defaultVal : (V) str.readObject());
}
Entry<K,V> middle = new Entry<>(key, value, null);
// color nodes in non-full bottommost level red
if (level == redLevel)
middle.color = RED;
if (left != null) {
middle.left = left;
left.parent = middle;
}
if (mid < hi) {
Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,
it, str, defaultVal);
middle.right = right;
right.parent = middle;
}
return middle;
}
三、Hashtable 線程同步、性能不好,故很少使用。
SortedMap是對Map的繼承,是一個有序排序
備註:
transient 表示數據不會存入硬盤,只能在內存中。