Map及其子类源码简单分析以及性能比较
2015-12-22 22:30
281 查看
1.HashMap
构造:key-value键值对,key采用hash函数来排列,加快查询速度/** * Associates the specified value with the specified key in this map. * If the map previously contained a mapping for the key, the old * value is replaced. * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return the previous value associated with <tt>key</tt>, or * <tt>null</tt> if there was no mapping for <tt>key</tt>. * (A <tt>null</tt> return can also indicate that the map * previously associated <tt>null</tt> with <tt>key</tt>.) */ public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { 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++; addEntry(hash, key, value, i); return null; }HashMap中key支持为null
<span style="white-space:pre"> </span>@Test public void Test(){ Map<String, String> map = new HashMap<String, String>(); map.put(null, "tom1"); map.put("key2", "tom2"); map.entrySet(); for(Entry<String, String> set:map.entrySet()){ System.out.println(set.getKey()+"<>"+map.get(set.getKey())); } }
2.TreeMap
构造:键值对,增加一个comparator参数对key进行默认排序/** * Constructs a new, empty tree map, ordered according to the given * comparator. All keys inserted into the map must be <em>mutually * comparable</em> by the given comparator: {@code comparator.compare(k1, * k2)} must not throw a {@code ClassCastException} for any keys * {@code k1} and {@code k2} in the map. If the user attempts to put * a key into the map that violates this constraint, the {@code put(Object * key, Object value)} call will throw a * {@code ClassCastException}. * * @param comparator the comparator that will be used to order this map. * If {@code null}, the {@linkplain Comparable natural * ordering} of the keys will be used. */ public TreeMap(Comparator<? super K> comparator) { this.comparator = comparator; }
put()时是即对key做排序,效率不会太高,所以只适用特定的环境
public V put(K key, V value) { Entry<K,V> t = root; if (t == null) { compare(key, key); // type (and possibly null) check root = new Entry<>(key, value, null); size = 1; modCount++; return null; } int cmp; Entry<K,V> parent; // split comparator and comparable paths Comparator<? super K> cpr = comparator; if (cpr != null) { do { parent = t; cmp = cpr.compare(key, t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } else { if (key == null) throw new NullPointerException(); Comparable<? super K> k = (Comparable<? super K>) key; do { parent = t; cmp = k.compareTo(t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } Entry<K,V> e = new Entry<>(key, value, parent); if (cmp < 0) parent.left = e; else parent.right = e; fixAfterInsertion(e); size++; modCount++; return null; }
3.ConcurrentHashMap
并发的HashMap,默认并发级别为16线程public ConcurrentHashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); }put写操作是线程安全的,且是并发写到segments中
/** * Maps the specified key to the specified value in this table. * Neither the key nor the value can be null. * * <p> The value can be retrieved by calling the <tt>get</tt> method * with a key that is equal to the original key. * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return the previous value associated with <tt>key</tt>, or * <tt>null</tt> if there was no mapping for <tt>key</tt> * @throws NullPointerException if the specified key or value is null */ @SuppressWarnings("unchecked") public V put(K key, V value) { Segment<K,V> s; if (value == null) throw new NullPointerException(); int hash = hash(key); int j = (hash >>> segmentShift) & segmentMask; if ((s = (Segment<K,V>)UNSAFE.getObject // nonvolatile; recheck (segments, (j << SSHIFT) + SBASE)) == null) // in ensureSegment s = ensureSegment(j); //确定哪个segment return s.put(key, hash, value, false); }
size()锁定所有segments,然后统计所有segments中的kv个数
/** * Returns the number of key-value mappings in this map. If the * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns * <tt>Integer.MAX_VALUE</tt>. * * @return the number of key-value mappings in this map */ public int size() { // Try a few times to get accurate count. On failure due to // continuous async changes in table, resort to locking. final Segment<K,V>[] segments = this.segments; int size; boolean overflow; // true if size overflows 32 bits long sum; // sum of modCounts long last = 0L; // previous sum int retries = -1; // first iteration isn't retry try { for (;;) { if (retries++ == RETRIES_BEFORE_LOCK) { for (int j = 0; j < segments.length; ++j) ensureSegment(j).lock(); // force creation 循环锁定所有segments } sum = 0L; size = 0; overflow = false; for (int j = 0; j < segments.length; ++j) { Segment<K,V> seg = segmentAt(segments, j); if (seg != null) { sum += seg.modCount; int c = seg.count; if (c < 0 || (size += c) < 0) overflow = true; } } if (sum == last) break; last = sum; } } finally { if (retries > RETRIES_BEFORE_LOCK) { for (int j = 0; j < segments.length; ++j) segmentAt(segments, j).unlock(); } } return overflow ? Integer.MAX_VALUE : size; }
4.后记
我的博客:http://blog.csdn.net/caicongyang记录与分享,你我共成长 -from caicongyang
相关文章推荐
- [LeetCode53]Maximum Subarray
- Redis 的性能
- python多线程实现售票
- 页面图片按钮案例
- ReentrantLock源码分析(JDK 1.7)
- 宣化上人:诸病从何来?
- ASCII、Unicode、GBK和UTF-8字符编码的区别联系
- swap 去除vector多余的容量
- Ceph 多节点quick部署
- 第二章 一切都是对象
- 宣化上人:这四句偈能治眼睛的病
- 固定于底部的图片返回按钮
- JVM生命周期和类加载机制
- Community detection
- MySQL GTID复制
- LA 3644 (并查集)
- The Apache Tomcat Native library which allows optimal performance in production environments was not
- java项目怎么加包而不是引用
- 在Docker中部署Subversion 1.9.3(CentOS7)
- 理解Java的类和对象