HashMap源码分析

来源:互联网 发布:c语言最大公约数流程图 编辑:程序博客网 时间:2024/06/07 10:29

一.HashMap源码


HashMap不同JDK版本源码应该有所不同,本文为 1.7


/*jadclipse*/// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.package java.util;import java.io.*;import java.security.AccessController;import sun.misc.Hashing;import sun.misc.VM;import sun.security.action.GetPropertyAction;// Referenced classes of package java.util://            AbstractMap, Arrays, Collection, Iterator, //            Map, Set, Objects, ConcurrentModificationException, //            NoSuchElementException, AbstractSet, AbstractCollectionpublic class HashMap extends AbstractMap implements Map, Cloneable, Serializable {static class Entry implements Map.Entry {public final Object getKey() {return key;}public final Object getValue() {return value;}public final Object setValue(Object obj) {Object obj1 = value;value = obj;return obj1;}public final boolean equals(Object obj) {if (!(obj instanceof Map.Entry))return false;Map.Entry entry = (Map.Entry) obj;Object obj1 = getKey();Object obj2 = entry.getKey();if (obj1 == obj2 || obj1 != null && obj1.equals(obj2)) {Object obj3 = getValue();Object obj4 = entry.getValue();if (obj3 == obj4 || obj3 != null && obj3.equals(obj4))return true;}return false;}public final int hashCode() {return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());}public final String toString() {return (new StringBuilder()).append(getKey()).append("=").append(getValue()).toString();}void recordAccess(HashMap hashmap) {}void recordRemoval(HashMap hashmap) {}final Object key;Object value;Entry next;int hash;Entry(int i, Object obj, Object obj1, Entry entry) {value = obj1;next = entry;key = obj;hash = i;}}private final class EntryIterator extends HashIterator {public Map.Entry next() {return nextEntry();}public volatile Object next() {return next();}final HashMap this$0;private EntryIterator() {this$0 = HashMap.this;super();}}private final class EntrySet extends AbstractSet {public Iterator iterator() {return newEntryIterator();}public boolean contains(Object obj) {if (!(obj instanceof Map.Entry)) {return false;} else {Map.Entry entry = (Map.Entry) obj;HashMap.Entry entry1 = getEntry(entry.getKey());return entry1 != null && entry1.equals(entry);}}public boolean remove(Object obj) {return removeMapping(obj) != null;}public int size() {return HashMap.this.size;}public void clear() {HashMap.this.clear();}final HashMap this$0;private EntrySet() {this$0 = HashMap.this;super();}}private abstract class HashIterator implements Iterator {public final boolean hasNext() {return next != null;}final HashMap.Entry nextEntry() {if (modCount != expectedModCount)throw new ConcurrentModificationException();HashMap.Entry entry = next;if (entry == null)throw new NoSuchElementException();if ((next = entry.next) == null) {for (HashMap.Entry aentry[] = table; index < aentry.length && (next = aentry[index++]) == null;);}current = entry;return entry;}public void remove() {if (current == null)throw new IllegalStateException();if (modCount != expectedModCount) {throw new ConcurrentModificationException();} else {Object obj = current.key;current = null;removeEntryForKey(obj);expectedModCount = modCount;return;}}HashMap.Entry next;int expectedModCount;int index;HashMap.Entry current;final HashMap this$0;HashIterator() {this$0 = HashMap.this;super();expectedModCount = modCount;if (size > 0) {for (HashMap.Entry aentry[] = table; index < aentry.length && (next = aentry[index++]) == null;);}}}private static class Holder {static final int ALTERNATIVE_HASHING_THRESHOLD;static {String s = (String) AccessController.doPrivileged(new GetPropertyAction("jdk.map.althashing.threshold"));int i;try {i = null == s ? 2147483647 : Integer.parseInt(s);if (i == -1)i = 2147483647;if (i < 0)throw new IllegalArgumentException("value must be positive integer.");} catch (IllegalArgumentException illegalargumentexception) {throw new Error("Illegal value for 'jdk.map.althashing.threshold'", illegalargumentexception);}ALTERNATIVE_HASHING_THRESHOLD = i;}private Holder() {}}private final class KeyIterator extends HashIterator {public Object next() {return nextEntry().getKey();}final HashMap this$0;private KeyIterator() {this$0 = HashMap.this;super();}}private final class KeySet extends AbstractSet {public Iterator iterator() {return newKeyIterator();}public int size() {return HashMap.this.size;}public boolean contains(Object obj) {return containsKey(obj);}public boolean remove(Object obj) {return removeEntryForKey(obj) != null;}public void clear() {HashMap.this.clear();}final HashMap this$0;private KeySet() {this$0 = HashMap.this;super();}}private final class ValueIterator extends HashIterator {public Object next() {return nextEntry().value;}final HashMap this$0;private ValueIterator() {this$0 = HashMap.this;super();}}private final class Values extends AbstractCollection {public Iterator iterator() {return newValueIterator();}public int size() {return HashMap.this.size;}public boolean contains(Object obj) {return containsValue(obj);}public void clear() {HashMap.this.clear();}final HashMap this$0;private Values() {this$0 = HashMap.this;super();}}public HashMap(int i, float f) {table = (Entry[]) EMPTY_TABLE;hashSeed = 0;entrySet = null;if (i < 0)throw new IllegalArgumentException((new StringBuilder()).append("Illegal initial capacity: ").append(i).toString());if (i > 1073741824)i = 1073741824;if (f <= 0.0F || Float.isNaN(f)) {throw new IllegalArgumentException((new StringBuilder()).append("Illegal load factor: ").append(f).toString());} else {loadFactor = f;threshold = i;init();return;}}public HashMap(int i) {this(i, 0.75F);}public HashMap() {this(16, 0.75F);}public HashMap(Map map) {this(Math.max((int) ((float) map.size() / 0.75F) + 1, 16), 0.75F);inflateTable(threshold);putAllForCreate(map);}private static int roundUpToPowerOf2(int i) {return i < 1073741824 ? i <= 1 ? 1 : Integer.highestOneBit(i - 1 << 1) : 1073741824;}private void inflateTable(int i) {int j = roundUpToPowerOf2(i);threshold = (int) Math.min((float) j * loadFactor, 1.073742E+009F);table = new Entry[j];initHashSeedAsNeeded(j);}void init() {}final boolean initHashSeedAsNeeded(int i) {boolean flag = hashSeed != 0;boolean flag1 = VM.isBooted() && i >= Holder.ALTERNATIVE_HASHING_THRESHOLD;boolean flag2 = flag ^ flag1;if (flag2)hashSeed = flag1 ? Hashing.randomHashSeed(this) : 0;return flag2;}final int hash(Object obj) {int i = hashSeed;if (0 != i && (obj instanceof String)) {return Hashing.stringHash32((String) obj);} else {i ^= obj.hashCode();i ^= i >>> 20 ^ i >>> 12;return i ^ i >>> 7 ^ i >>> 4;}}static int indexFor(int i, int j) {return i & j - 1;}public int size() {return size;}public boolean isEmpty() {return size == 0;}public Object get(Object obj) {if (obj == null) {return getForNullKey();} else {Entry entry = getEntry(obj);return null != entry ? entry.getValue() : null;}}private Object getForNullKey() {if (size == 0)return null;for (Entry entry = table[0]; entry != null; entry = entry.next)if (entry.key == null)return entry.value;return null;}public boolean containsKey(Object obj) {return getEntry(obj) != null;}final Entry getEntry(Object obj) {if (size == 0)return null;int i = obj != null ? hash(obj) : 0;for (Entry entry = table[indexFor(i, table.length)]; entry != null; entry = entry.next) {Object obj1;if (entry.hash == i && ((obj1 = entry.key) == obj || obj != null && obj.equals(obj1)))return entry;}return null;}public Object put(Object obj, Object obj1) {if (table == EMPTY_TABLE)inflateTable(threshold);if (obj == null)return putForNullKey(obj1);int i = hash(obj);int j = indexFor(i, table.length);for (Entry entry = table[j]; entry != null; entry = entry.next) {Object obj2;if (entry.hash == i && ((obj2 = entry.key) == obj || obj.equals(obj2))) {Object obj3 = entry.value;entry.value = obj1;entry.recordAccess(this);return obj3;}}modCount++;addEntry(i, obj, obj1, j);return null;}private Object putForNullKey(Object obj) {for (Entry entry = table[0]; entry != null; entry = entry.next)if (entry.key == null) {Object obj1 = entry.value;entry.value = obj;entry.recordAccess(this);return obj1;}modCount++;addEntry(0, null, obj, 0);return null;}private void putForCreate(Object obj, Object obj1) {int i = null != obj ? hash(obj) : 0;int j = indexFor(i, table.length);for (Entry entry = table[j]; entry != null; entry = entry.next) {Object obj2;if (entry.hash == i && ((obj2 = entry.key) == obj || obj != null && obj.equals(obj2))) {entry.value = obj1;return;}}createEntry(i, obj, obj1, j);}private void putAllForCreate(Map map) {Map.Entry entry;for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext(); putForCreate(entry.getKey(),entry.getValue()))entry = (Map.Entry) iterator.next();}void resize(int i) {Entry aentry[] = table;int j = aentry.length;if (j == 1073741824) {threshold = 2147483647;return;} else {Entry aentry1[] = new Entry[i];transfer(aentry1, initHashSeedAsNeeded(i));table = aentry1;threshold = (int) Math.min((float) i * loadFactor, 1.073742E+009F);return;}}void transfer(Entry aentry[], boolean flag) {int i = aentry.length;Entry aentry1[] = table;int j = aentry1.length;for (int k = 0; k < j; k++) {Entry entry1;for (Entry entry = aentry1[k]; null != entry; entry = entry1) {entry1 = entry.next;if (flag)entry.hash = null != entry.key ? hash(entry.key) : 0;int l = indexFor(entry.hash, i);entry.next = aentry[l];aentry[l] = entry;}}}public void putAll(Map map) {int i = map.size();if (i == 0)return;if (table == EMPTY_TABLE)inflateTable((int) Math.max((float) i * loadFactor, threshold));if (i > threshold) {int j = (int) ((float) i / loadFactor + 1.0F);if (j > 1073741824)j = 1073741824;int k;for (k = table.length; k < j; k <<= 1);if (k > table.length)resize(k);}Map.Entry entry;for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext(); put(entry.getKey(), entry.getValue()))entry = (Map.Entry) iterator.next();}public Object remove(Object obj) {Entry entry = removeEntryForKey(obj);return entry != null ? entry.value : null;}final Entry removeEntryForKey(Object obj) {if (size == 0)return null;int i = obj != null ? hash(obj) : 0;int j = indexFor(i, table.length);Entry entry = table[j];Entry entry1;Entry entry2;for (entry1 = entry; entry1 != null; entry1 = entry2) {entry2 = entry1.next;Object obj1;if (entry1.hash == i && ((obj1 = entry1.key) == obj || obj != null && obj.equals(obj1))) {modCount++;size--;if (entry == entry1)table[j] = entry2;elseentry.next = entry2;entry1.recordRemoval(this);return entry1;}entry = entry1;}return entry1;}final Entry removeMapping(Object obj) {if (size == 0 || !(obj instanceof Map.Entry))return null;Map.Entry entry = (Map.Entry) obj;Object obj1 = entry.getKey();int i = obj1 != null ? hash(obj1) : 0;int j = indexFor(i, table.length);Entry entry1 = table[j];Entry entry2;Entry entry3;for (entry2 = entry1; entry2 != null; entry2 = entry3) {entry3 = entry2.next;if (entry2.hash == i && entry2.equals(entry)) {modCount++;size--;if (entry1 == entry2)table[j] = entry3;elseentry1.next = entry3;entry2.recordRemoval(this);return entry2;}entry1 = entry2;}return entry2;}public void clear() {modCount++;Arrays.fill(table, null);size = 0;}public boolean containsValue(Object obj) {if (obj == null)return containsNullValue();Entry aentry[] = table;for (int i = 0; i < aentry.length; i++) {for (Entry entry = aentry[i]; entry != null; entry = entry.next)if (obj.equals(entry.value))return true;}return false;}private boolean containsNullValue() {Entry aentry[] = table;for (int i = 0; i < aentry.length; i++) {for (Entry entry = aentry[i]; entry != null; entry = entry.next)if (entry.value == null)return true;}return false;}public Object clone() {HashMap hashmap = null;try {hashmap = (HashMap) super.clone();} catch (CloneNotSupportedException clonenotsupportedexception) {}if (hashmap.table != EMPTY_TABLE)hashmap.inflateTable(Math.min((int) Math.min((float) size * Math.min(1.0F / loadFactor, 4F), 1.073742E+009F), table.length));hashmap.entrySet = null;hashmap.modCount = 0;hashmap.size = 0;hashmap.init();hashmap.putAllForCreate(this);return hashmap;}void addEntry(int i, Object obj, Object obj1, int j) {if (size >= threshold && null != table[j]) {resize(2 * table.length);i = null == obj ? 0 : hash(obj);j = indexFor(i, table.length);}createEntry(i, obj, obj1, j);}void createEntry(int i, Object obj, Object obj1, int j) {Entry entry = table[j];table[j] = new Entry(i, obj, obj1, entry);size++;}Iterator newKeyIterator() {return new KeyIterator();}Iterator newValueIterator() {return new ValueIterator();}Iterator newEntryIterator() {return new EntryIterator();}public Set keySet() {Set set = keySet;return set == null ? (keySet = new KeySet()) : set;}public Collection values() {Collection collection = values;return collection == null ? (values = new Values()) : collection;}public Set entrySet() {return entrySet0();}private Set entrySet0() {Set set = entrySet;return set == null ? (entrySet = new EntrySet()) : set;}private void writeObject(ObjectOutputStream objectoutputstream) throws IOException {objectoutputstream.defaultWriteObject();if (table == EMPTY_TABLE)objectoutputstream.writeInt(roundUpToPowerOf2(threshold));elseobjectoutputstream.writeInt(table.length);objectoutputstream.writeInt(size);if (size > 0) {Map.Entry entry;for (Iterator iterator = entrySet0().iterator(); iterator.hasNext(); objectoutputstream.writeObject(entry.getValue())) {entry = (Map.Entry) iterator.next();objectoutputstream.writeObject(entry.getKey());}}}private void readObject(ObjectInputStream objectinputstream) throws IOException, ClassNotFoundException {objectinputstream.defaultReadObject();if (loadFactor <= 0.0F || Float.isNaN(loadFactor))throw new InvalidObjectException((new StringBuilder()).append("Illegal load factor: ").append(loadFactor).toString());table = (Entry[]) EMPTY_TABLE;objectinputstream.readInt();int i = objectinputstream.readInt();if (i < 0)throw new InvalidObjectException((new StringBuilder()).append("Illegal mappings count: ").append(i).toString());int j = (int) Math.min((float) i * Math.min(1.0F / loadFactor, 4F), 1.073742E+009F);if (i > 0)inflateTable(j);elsethreshold = j;init();for (int k = 0; k < i; k++) {Object obj = objectinputstream.readObject();Object obj1 = objectinputstream.readObject();putForCreate(obj, obj1);}}int capacity() {return table.length;}float loadFactor() {return loadFactor;}static final int DEFAULT_INITIAL_CAPACITY = 16;static final int MAXIMUM_CAPACITY = 1073741824;static final float DEFAULT_LOAD_FACTOR = 0.75F;static final Entry EMPTY_TABLE[] = new Entry[0];transient Entry table[];transient int size;int threshold;final float loadFactor;transient int modCount;static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = 2147483647;transient int hashSeed;private transient Set entrySet;private static final long serialVersionUID = 362498820763181265L;}/*DECOMPILATION REPORTDecompiled from: C:\Program Files\Java\jre7\lib\rt.jarTotal time: 44 msJad reported messages/errors:Exit status: 0Caught exceptions:*/





0 0
原创粉丝点击