Map:Map是一个接口,它定义了一些规则,即get和put操作。Map用于保存具有映射关系的数据,因此Map集合中存的是键值对,并且key不能重复
HashMap:HashMap是Map接口的一个实现类。HashMap提供所有可选的映射操作,并且允许存null键和null值,它不保证映射的顺序,特别是不保证该顺序永远不发生改变。HashMap的迭代所需的时间和HashMap实例的“容量”(桶的数量)以及大小(里面键值对的数量)成比例。
影响HashMap性能的两个参数:初始容量和加载因子。容量就是哈希表中桶的数量,初始容量只是哈希表在创建时的容量,加载因子是哈希表在其容量自动增加之前达到多满的一种程度,比如默认的加载因子是0.75,初始容量是100,那么当哈希表中的条目数量达到0.75 * 100 = 75时,则要对哈希表进行rehash操作(即重建内部结构),从而将哈希表的桶数翻倍。
HashMap是不同步的,所以在多线程访问同一个哈希表的时候,需要在外部进行同步,比如
Map map = Collections.synchronizedMap(new HashMap(...));
HashMap的迭代:由所有此类的"Collection视图方法"所返回的迭代器都是快速失败的:在迭代器创建之后,如果要对HashMap结构进行修改,建议通过迭代器本身的remove()和add()
HashMap的遍历:可以通过获取到HashMap的keySet,然后通过keySet里面的key去取value
HashMap<String,String> hashMap = new HashMap<String,String)();
for(String key:hashMap.keySet()){
String value = hashMap.get(key);
}
HashMap设计思路
HashMap假定哈希函数将元素正确分布在各桶之间,可为get和put提供稳定的性能。迭代视图所需的时间与HashMap实例的“容量”及其大小成比例
HashMap重写的方法:因为HashMap是基于HashCode的,在Object类中有一个HashCode方法,这个方法返回的HashCode对应于当前的地址,也就是说不同的对象,即使它们的内容完全一样所得到的哈希值也会不一样,所以就跟复写equals方法一样,要重新定义hashCode的实现
重写HashCode的原则:1.不唯一原则:不必对每个不同的对象都产生一个唯一的hashcode,只要设计的hashCode方法能get到put进去的内容就可以了;
2.分散原则:hashCode算法生成的值要分散一些,不要很多的hashcode都集中在一个范围,这样有利于提高HashMap的性能
对HashMap的分析
1.HashMap是实现了Map Cloneable Serializable并继承了AbstractMap的类,最重要的是里面有一个实现了Map.Entry的静态内部类HashMapEntry,里面包含了key value next hash四个属性
static class HashMapEntry<K, V> implements Entry<K, V> {
final K key;
V value;
final int hash;
HashMapEntry<K, V> next;
HashMapEntry(K key, V value, int hash, HashMapEntry<K, V> next) {
this.key = key;
this.value = value;
this.hash = hash;
this.next = next;
}
public final K getKey() {
return key;
}