一、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 表示数据不会存入硬盘,只能在内存中。