/**
*
* @(#) Main.java
* @Package com.map
*
* Copyright © JING Corporation. All rights reserved.
*
*/
package com.map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* 类描述:Run Config设置vm参数:-Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M
*
* @author: Jing History: Jan 21, 2015 10:14:20 AM Jing Created.
*
*/
public class Main {
public static void main(String[] args) {
// HashMap 插入效率
Map<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
long startTime = System.currentTimeMillis();
addData(hashMap);
long endTime = System.currentTimeMillis();
System.out.println("HashMap插入1000000条数据,用时: " + (endTime - startTime));// 272
startTime = System.currentTimeMillis();
iterMap(hashMap);
endTime = System.currentTimeMillis();
System.out.println("HashMap遍历1000000条数据,用时: " + (endTime - startTime));// 84
// System.out.println(hashMap.toString());
// LinkedHashMap
Map<Integer, Integer> linkedHashMap = new LinkedHashMap<Integer, Integer>();
startTime = System.currentTimeMillis();
addData(linkedHashMap);
endTime = System.currentTimeMillis();
System.out.println("LinkedHashMap插入1000000条数据,用时: "
+ (endTime - startTime));// 551 LinkedHashMap HashMap
// 插入和遍历的数据越大,数值的差异越明显
startTime = System.currentTimeMillis();
iterMap(linkedHashMap);
endTime = System.currentTimeMillis();
System.out.println("LinkedHashMap遍历1000000条数据,用时: "
+ (endTime - startTime));// 85 LinkedHashMap HashMap
// 插入和遍历的数据越大,数值的越接近
// System.out.println(linkedHashMap.toString());
Map<Integer, Integer> treeMap = new TreeMap<Integer, Integer>();
startTime = System.currentTimeMillis();
addData(treeMap);
endTime = System.currentTimeMillis();
System.out.println(" TreeMap插入1000000条数据,用时: " + (endTime - startTime));// 491
startTime = System.currentTimeMillis();
iterMap(treeMap);
endTime = System.currentTimeMillis();
System.out.println(" TreeMap遍历1000000条数据,用时: " + (endTime - startTime));// 538
// System.out.println(treeMap.toString());
}
/**
*
* 方法说明:向Map中添加数据
*
* Author: Jing Create Date: Jan 21, 2015 10:40:18 AM
*/
static void addData(Map<Integer, Integer> map) {
for (int i = 0; i <= 1000000; i++) {
int value = (int) (Math.random() * i);
map.put(i, value);
}
}
/**
*
* 方法说明:遍历Map
*
* Author: Jing Create Date: Jan 21, 2015 10:41:00 AM
*/
static void iterMap(Map<Integer, Integer> map) {
Set<Integer> keySet = map.keySet();
Iterator<Integer> iter = keySet.iterator();
while (iter.hasNext()) {
int key = iter.next();
map.get(key);
}
}
}
static final int DEFAULT_INITIAL_CAPACITY = 16;
static final int MAXIMUM_CAPACITY = 1 << 30;
static final float DEFAULT_LOAD_FACTOR = 0.75f;
transient Entry[] table;
transient int size;
int threshold;
transient volatile int modCount;
// Views
private transient Set<Map.Entry<K,V>> entrySet = null;
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);//如果key为空,执行
putForNullKey方法int hash = hash(key.hashCode());//获取到key对应的hashCode值
int i = indexFor(hash, table.length);//求取对应hashCode值在table中的位置
for (Entry<K,V> e = table[i]; e != null; e = e.next) {//判断对应算出哈希表中的位置是否存在元素,如果存在元素,判断该Entry链。如果hash值相等,并且key相同,则替换值
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;//结构化修改计数器加1
addEntry(hash, key, value, i);//在对应哈希表的位置中增加Entry对象。
return null;
}
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;//链表,标识同一哈希值的下一实体
final int hash;
private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {//查找table中的null key替换value
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
return null;
}
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
if (size++ >= threshold)//存储元素加1,并在加1后判断是否超过了阀值,阀值在初始化HashMap时初始化。
resize(2 * table.length);
}
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());//获取哈希值
for (Entry<K,V> e = table[indexFor(hash, table.length)];//获取对应哈希值的Entry链,遍历Entry链,查找到对应key的Entry对像,返回对应Entry的value。
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
public V remove(Object key) {
Entry<K,V> e = removeEntryForKey(key);
return (e == null ? null : e.value);
}
final Entry<K,V> removeEntryForKey(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());//获取hash值
int i = indexFor(hash, table.length);//hash在哈希表中的位置
Entry<K,V> prev = table[i];//获取对应值的Entry链的首元素
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;//遍历Entry链,查找值,从Entry链中移除
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {
modCount++;
size--;
if (prev == e)
table[i] = next;
else
prev.next = next;
e.recordRemoval(this);
return e;
}
prev = e;
e = next;
}
return e;
}
private abstract class HashIterator<E> implements Iterator<E> {
Entry<K,V> next; // next entry to return
int expectedModCount; // For fast-fail
int index; // current slot
Entry<K,V> current; // current entry
HashIterator() {
expectedModCount = modCount;
if (size > 0) { // advance to first entry
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
}
public final boolean hasNext() {
return next != null;
}
final Entry<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if ((next = e.next) == null) {
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
current = e;
return e;
}
public void remove() {
if (current == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Object k = current.key;
current = null;
HashMap.this.removeEntryForKey(k);
expectedModCount = modCount;
}
}
private final class KeySet extends AbstractSet<K> {
public Iterator<K> iterator() {
return newKeyIterator();
}
public int size() {
return size;
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
return HashMap.this.removeEntryForKey(o) != null;
}
public void clear() {
HashMap.this.clear();
}
}
private final class ValueIterator extends HashIterator<V> {
public V next() {
return nextEntry().value;
}
}
private final class KeyIterator extends HashIterator<K> {
public K next() {
return nextEntry().getKey();
}
}
private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
public Map.Entry<K,V> next() {
return nextEntry();
}
}
private transient Entry<K,V> header;
private static class Entry<K,V> extends HashMap.Entry<K,V> {
// These fields comprise the doubly linked list used for iteration.
Entry<K,V> before, after;
Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
super(hash, key, value, next);
}
/**
* Removes this entry from the linked list.
*/
private void remove() {
before.after = after;
after.before = before;
}
/**
* Inserts this entry before the specified existing entry in the list.
*/
private void addBefore(Entry<K,V> existingEntry) {
after = existingEntry;
before = existingEntry.before;
before.after = this;
after.before = this;
}