//The main difference from HashMap is that == is used to judge the equality of keys //The map calculates the hash value using the System.identityHashCode method. //And the map will store the key at the i position and the value at the i+1 position. //Look at the constructor first: public IdentityHashMap() { init(DEFAULT_CAPACITY); } //Initialize a map with 2 times the size of initCapacity private void init(int initCapacity) { threshold = (initCapacity * 2)/3; table = new Object[2 * initCapacity]; } public IdentityHashMap(int expectedMaxSize) { if (expectedMaxSize < 0) throw new IllegalArgumentException("expectedMaxSize is negative: " + expectedMaxSize); init(capacity(expectedMaxSize)); } public IdentityHashMap(Map<? extends K, ? extends V> m) { // Allow for a bit of growth this((int) ((1 + m.size()) * 1.1)); putAll(m); } //add element public V put(K key, V value) { //Convert empty key to object Object k = maskNull(key); Object[] tab = table; int len = tab.length; int i = hash(k, len); Object item; while ( (item = tab[i]) != null) { //Note that the key here is only used for == comparison if (item == k) { V oldValue = (V) tab[i + 1]; tab[i + 1] = value; return oldValue; } i = nextKeyIndex(i, len); } modCount++; tab[i] = k; tab[i + 1] = value; //expand if (++size >= threshold) resize(len); // len == 2 * current capacity. return null; } //Calculate the hash value private static int hash(Object x, int length) { int h = System.identityHashCode(x); // Multiply by -127, and left-shift to use least bit as part of hash return ((h << 1) - (h << 8)) & (length - 1); } //i+2 private static int nextKeyIndex(int i, int len) { return (i + 2 < len ? i + 2 : 0); } // get the value according to the key public V get(Object key) { Object k = maskNull(key); Object[] tab = table; int len = tab.length; int i = hash(k, len); while (true) { Object item = tab[i]; if (item == k) return (V) tab[i + 1]; if (item == null) return null; i = nextKeyIndex(i, len); } } //return the number of elements public int size() { return size; } //Is the collection empty public boolean isEmpty() { return size == 0; } // Does it contain a key public boolean containsKey(Object key) { Object k = maskNull(key); Object[] tab = table; int len = tab.length; int i = hash(k, len); while (true) { Object item = tab[i]; if (item == k) return true; if (item == null) return false; i = nextKeyIndex(i, len); } } // does it contain a value public boolean containsValue(Object value) { Object[] tab = table; for (int i = 1; i < tab.length; i += 2) if (tab[i] == value && tab[i - 1] != null) return true; return false; } // whether to include a map private boolean containsMapping(Object key, Object value) { Object k = maskNull(key); Object[] tab = table; int len = tab.length; int i = hash(k, len); while (true) { Object item = tab[i]; if (item == k) return tab[i + 1] == value; if (item == null) return false; i = nextKeyIndex(i, len); } } //Delete the map according to the key public V remove(Object key) { Object k = maskNull(key); Object[] tab = table; int len = tab.length; int i = hash(k, len); while (true) { Object item = tab[i]; if (item == k) { modCount++; size--; V oldValue = (V) tab[i + 1]; tab[i + 1] = null; tab[i] = null; // reposition the element closeDeletion(i); return oldValue; } if (item == null) return null; i = nextKeyIndex(i, len); } } private void closeDeletion(int d) { Object[] tab = table; int len = tab.length; Object item; for (int i = nextKeyIndex(d, len); (item = tab[i]) != null; i = nextKeyIndex(i, len) ) { int r = hash(item, len); if ((i < r && (r <= d || d <= i)) || (r <= d && d <= i)) { tab[d] = item; tab[d + 1] = tab[i + 1]; tab[i] = null; tab[i + 1] = null; d = i; } } } // clear the array public void clear() { modCount++; Object[] tab = table; for (int i = 0; i < tab.length; i++) tab[i] = null; size = 0; }
Read the IdentityHashMap source code
Guess you like
Origin http://43.154.161.224:23101/article/api/json?id=326398656&siteId=291194637
Recommended
Ranking