HashMap简介:
HashMap是一个散列表,存储的内容是键值对(key-value)映射。HashMap继承于AbstractMap并实现了Map、Cloneable、Serializable接口。
从结构实现来讲,HashMap 是数组 + 链表 + 红黑树(JDK1.8 增加了红黑树部分)实现的。
它根据键的 hashCode 值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。
HashMap 最多只允许一条记录的键为 null,允许多条记录的值为 null。
HashMap 使用 hash 算法进行数据的存储和查询。
内部使用一个 Entry 表示键值对 key-value。
用 Entry 的数组保存所有键值对, Entry 通过链表的方式链接后续的节点 (1.8 后会根据链表长度决定是否转换成一棵树类似 TreeMap 来节省查询时间) Entry 通过计算 key 的 hash 值来决定映射到具体的哪个数组(也叫 Bucket) 中。
HashMap 非线程安全,即任一时刻可以有多个线程同时写 HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections 的 synchronizedMap 方法使 HashMap 具有线程安全的能力,或者使用 ConcurrentHashMap。
(1)HashMap不是线程安全的,同时key-value都可以为null,并且是无序的。
(2)HashMap的初始大小为16,最大大小为2的30次方,默认的加载因子是0.75。
(3)初始容量只是哈希表在创建时的容量,加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,就需要对该哈希表进行rehash操作(重建内部的数据结构)
Map与HashMap
(1)HashMap继承于AbstractMap类,实现了Map接口。
(2)HashMap通过拉链法实现哈希表。几个重要的成员变量有:table,size,threshold,loadFactor,modCount。
table是一个Entry[]数组类型,Entry实际上是一个单向链表,HashMap的key-value都存储在这个数组中。
size是HashMap的大小,它是HashMap保存的键值对的数量。
threshold是HashMap的阈值,用于判断是否需要调整HashMap的容量,threshold的值等于容量乘以加载因子,当HashMap中存储的数据达到threshold时,就需要将HashMap的容量加倍。
loadFactor加载因子
modCount用来实现fail-fast机制。
HashMap的遍历方式:
(1)遍历HashMap的键值对:第一步是获得通过entrySet()函数获得entry集合,第二步通过Iterator迭代器遍历entry集合获得数据
Stringkey;
Integer value;
Iterator iterator=map.entrySet().iterator();
while(iterator.hasNext())
{
Map.Entry entry=(Map.Entry)iterator.next();
key=(String)enrty.getKey();
value=(Integer)entry.getValue();
}
(2)遍历HashMap的键,通过key来获得value
Stringkey=null;
Integer value=null;
Inerator iterator=map.keySet().iterator();
while(iterator.hasNext())
{
key=(String)iterator.next();
value=(Integer)map.get(key);
}
(3)遍历HashMap的值:第一步根据value获得值集合,对值集合进行迭代遍历
Integervalue=null;
Collection c=map.values();
Iterator iterator = c.iterator();
while(iterator.hasNext())
{
value=(Integer)iterator.next();
}
常用的函数:
void clear()
Object clone()
boolean containsKey(Object key)
boolean containsValue(Object value)
Set<Entry<K, V>> entrySet()
V get(Object key)
boolean isEmpty()
Set<K> keySet()
V put(K key, V value)
void putAll(Map<? extends K, ? extends V> map)
V remove(Object key)
int size()
Collection<V> values()
HashMap示例代码:
public class Hello {
public void testHashMapAPIs()
{
Random r = new Random();
HashMap<String,Integer> map = new HashMap();
map.put("one", r.nextInt(10));
map.put("two", r.nextInt(10));
map.put("three", r.nextInt(10));
System.out.println("map:"+map );
Iterator iter = map.entrySet().iterator();
while(iter.hasNext())
{
Map.Entry entry = (Map.Entry)iter.next();
System.out.println("key : "+ entry.getKey() +",value:"+entry.getValue());
}
System.out.println("size:"+map.size());
System.out.println("contains key two : "+map.containsKey("two"));
System.out.println("contains key five : "+map.containsKey("five"));
System.out.println("contains value 0 : "+map.containsValue(new Integer(0)));
map.remove("three");
System.out.println("map:"+map );
map.clear();
System.out.println((map.isEmpty()?"map is empty":"map is not empty") );
}
public static void main(String[] args) {
Hello hello=new Hello();
hello.testHashMapAPIs();
}
}
运行结果:
map:{one=3, two=9, three=9}
key : one,value:3
key : two,value:9
key : three,value:9
size:3
contains key two : true
contains key five : false
contains value 0 : false
map:{one=3, two=9}
map is empty