HashMap继承AbstractMap
抽象类Map
接口和Cloneable
接口。Map接口如下方法,JDK1.8实现了一些默认方法
public interface Map<K,V>{//K和v是类型参数,分别表示键(Key)和值( Value)的类型
V put(K key, V value);//保存键值对,如果原来有key,覆盖,返回原来的值
V get( Object key);//根据键获取值,没找到,返回nu11
V remove( Object key);//根据键删除键值对,返回key原来的值,如果不存在,返回nu11
int size();//査看Map中键值对的个数
boolean isempty();//是否为空
boolean containskey( Object key);//查看是否包含某个键
boolean containsvalue( Object value);//查看是否包含某个值
void puta11(Map<? extends K,? extends V>m);//保存m中的所有键值对到当前Map
void clear();//清空Map中所有键值对
Set<K> keyset();//获取Map中键的集合
Collection lection<V> values();//获取Map中所有值的集合
Set<Map. Entry<K,V>> entryset();//获取Map中的所有键值对
interface Entry.<K,V> {//嵌套接口,表示一条键值对
K getkey();//键值对的键
V getvalue ();//键值对的值
V setvalue (V value);
boolean equals (Object o);
int hashcode ();
}
boolean equals(Object o);
int hashcode();
boolean containsvalue(Object value);
使用Map键是唯一,键keySet()方法返回的是Set,根据键可以删除键值对。
HashMap构造方法,还有其它二个构造方法
1.默认构造一个DEFAULT_LOAD_FACTOR负载因子0.75f方法
2.参数设置initialCapacity初始容量
和负载因子
loadFactor的初始值
//1
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
//2
public HashMap(int initialCapacity, float loadFactor){
..
}
HashMap默认变量,其它方法变量主要是操作这些静态变量
//默认是16的容量
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
//最大容量不能超过 1073741824
static final int MAXIMUM_CAPACITY = 1 << 30;
//负载因子0.75
static final float DEFAULT_LOAD_FACTOR = 0.75f;
//变树的阈值
static final int TREEIFY_THRESHOLD = 8;
//树退化链表阈值
static final int UNTREEIFY_THRESHOLD = 6;
//最小树容量,生成树最小容量64,阈值8
static final int MIN_TREEIFY_CAPACITY = 64;
hashMap最上面还有一个静态内部类,像这些是要被调用才会执行。不像静态方法静态变量一开始就加载到方法区
//链表的节点
static class Node<K,V> implements Map.Entry<K,V> { ..
//红黑树的节点
static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {..
1.table是一个Entry类型的数组
2.entrySet
3.size实际键值对的个数
4.modCount改变的次数,在遍历如果有修改添加会报异常ConcurrentModificationException
5.threshold表示阈值,当size个数大于等于threshold阈值扩容,例如table长度是16.loadFactor是0.75f,计算是16x0.74=12
得出阈值是12,负载因子可以通过构造方法修改
6.loadFactor 负载因子
transient HashMap.Node<K,V>[] table;
transient Set<Map.Entry<K,V>> entrySet;
transient int size;
transient int modCount;
int threshold;
final float loadFactor;
HashMap JDK1.8是数组+链表+树,add()添加一次默认分配16容量的数组。扩容16计算负载因子得出是12.扩容是容量得2倍。内部有数组table[],每个元素table[i]指向一个单向链表。用键算出hash值,取模拿到数组中得索引位置,然后操作数组指向得单向链表。
在链表上操作是比较hash值,相同用equals方法比较,equals首先默认比较对象(==)引用地址相等,
然后比较是否字符串String,一个个转成char字符内容比较。
自定义对象要重写hashCode值和equals。Object有hashCode,返回值是int类型,代表每个对象重写都有hash值,如果像Stirng对象每个对象都有hash值。这个hash值在对象里面用不到,集合map中能用到。
hashCode相等,则对象不一定相等。对象相等hash一定相等。存储对象依赖hash值,根据hash值比较不依赖对象比较,可以提高效率吧