jdk/src/share/classes/java/util/IdentityHashMap.java
changeset 12448 b95438b17098
parent 10419 12c063b39232
child 14342 8435a30053c1
equal deleted inserted replaced
12447:92676a77a667 12448:b95438b17098
   325      * The {@link #containsKey containsKey} operation may be used to
   325      * The {@link #containsKey containsKey} operation may be used to
   326      * distinguish these two cases.
   326      * distinguish these two cases.
   327      *
   327      *
   328      * @see #put(Object, Object)
   328      * @see #put(Object, Object)
   329      */
   329      */
       
   330     @SuppressWarnings("unchecked")
   330     public V get(Object key) {
   331     public V get(Object key) {
   331         Object k = maskNull(key);
   332         Object k = maskNull(key);
   332         Object[] tab = table;
   333         Object[] tab = table;
   333         int len = tab.length;
   334         int len = tab.length;
   334         int i = hash(k, len);
   335         int i = hash(k, len);
   429         int i = hash(k, len);
   430         int i = hash(k, len);
   430 
   431 
   431         Object item;
   432         Object item;
   432         while ( (item = tab[i]) != null) {
   433         while ( (item = tab[i]) != null) {
   433             if (item == k) {
   434             if (item == k) {
   434                 V oldValue = (V) tab[i + 1];
   435                 @SuppressWarnings("unchecked")
       
   436                     V oldValue = (V) tab[i + 1];
   435                 tab[i + 1] = value;
   437                 tab[i + 1] = value;
   436                 return oldValue;
   438                 return oldValue;
   437             }
   439             }
   438             i = nextKeyIndex(i, len);
   440             i = nextKeyIndex(i, len);
   439         }
   441         }
   522         while (true) {
   524         while (true) {
   523             Object item = tab[i];
   525             Object item = tab[i];
   524             if (item == k) {
   526             if (item == k) {
   525                 modCount++;
   527                 modCount++;
   526                 size--;
   528                 size--;
   527                 V oldValue = (V) tab[i + 1];
   529                 @SuppressWarnings("unchecked")
       
   530                     V oldValue = (V) tab[i + 1];
   528                 tab[i + 1] = null;
   531                 tab[i + 1] = null;
   529                 tab[i] = null;
   532                 tab[i] = null;
   530                 closeDeletion(i);
   533                 closeDeletion(i);
   531                 return oldValue;
   534                 return oldValue;
   532             }
   535             }
   636      */
   639      */
   637     public boolean equals(Object o) {
   640     public boolean equals(Object o) {
   638         if (o == this) {
   641         if (o == this) {
   639             return true;
   642             return true;
   640         } else if (o instanceof IdentityHashMap) {
   643         } else if (o instanceof IdentityHashMap) {
   641             IdentityHashMap m = (IdentityHashMap) o;
   644             IdentityHashMap<?,?> m = (IdentityHashMap<?,?>) o;
   642             if (m.size() != size)
   645             if (m.size() != size)
   643                 return false;
   646                 return false;
   644 
   647 
   645             Object[] tab = m.table;
   648             Object[] tab = m.table;
   646             for (int i = 0; i < tab.length; i+=2) {
   649             for (int i = 0; i < tab.length; i+=2) {
   648                 if (k != null && !containsMapping(k, tab[i + 1]))
   651                 if (k != null && !containsMapping(k, tab[i + 1]))
   649                     return false;
   652                     return false;
   650             }
   653             }
   651             return true;
   654             return true;
   652         } else if (o instanceof Map) {
   655         } else if (o instanceof Map) {
   653             Map m = (Map)o;
   656             Map<?,?> m = (Map<?,?>)o;
   654             return entrySet().equals(m.entrySet());
   657             return entrySet().equals(m.entrySet());
   655         } else {
   658         } else {
   656             return false;  // o is not a Map
   659             return false;  // o is not a Map
   657         }
   660         }
   658     }
   661     }
   696      *
   699      *
   697      * @return a shallow copy of this map
   700      * @return a shallow copy of this map
   698      */
   701      */
   699     public Object clone() {
   702     public Object clone() {
   700         try {
   703         try {
   701             IdentityHashMap<K,V> m = (IdentityHashMap<K,V>) super.clone();
   704             IdentityHashMap<?,?> m = (IdentityHashMap<?,?>) super.clone();
   702             m.entrySet = null;
   705             m.entrySet = null;
   703             m.table = table.clone();
   706             m.table = table.clone();
   704             return m;
   707             return m;
   705         } catch (CloneNotSupportedException e) {
   708         } catch (CloneNotSupportedException e) {
   706             throw new InternalError(e);
   709             throw new InternalError(e);
   766 
   769 
   767             Object[] tab = traversalTable;
   770             Object[] tab = traversalTable;
   768             int len = tab.length;
   771             int len = tab.length;
   769 
   772 
   770             int d = deletedSlot;
   773             int d = deletedSlot;
   771             K key = (K) tab[d];
   774             Object key = tab[d];
   772             tab[d] = null;        // vacate the slot
   775             tab[d] = null;        // vacate the slot
   773             tab[d + 1] = null;
   776             tab[d + 1] = null;
   774 
   777 
   775             // If traversing a copy, remove in real table.
   778             // If traversing a copy, remove in real table.
   776             // We can skip gap-closure on copy.
   779             // We can skip gap-closure on copy.
   816             }
   819             }
   817         }
   820         }
   818     }
   821     }
   819 
   822 
   820     private class KeyIterator extends IdentityHashMapIterator<K> {
   823     private class KeyIterator extends IdentityHashMapIterator<K> {
       
   824         @SuppressWarnings("unchecked")
   821         public K next() {
   825         public K next() {
   822             return (K) unmaskNull(traversalTable[nextIndex()]);
   826             return (K) unmaskNull(traversalTable[nextIndex()]);
   823         }
   827         }
   824     }
   828     }
   825 
   829 
   826     private class ValueIterator extends IdentityHashMapIterator<V> {
   830     private class ValueIterator extends IdentityHashMapIterator<V> {
       
   831         @SuppressWarnings("unchecked")
   827         public V next() {
   832         public V next() {
   828             return (V) traversalTable[nextIndex() + 1];
   833             return (V) traversalTable[nextIndex() + 1];
   829         }
   834         }
   830     }
   835     }
   831 
   836 
   852 
   857 
   853             private Entry(int index) {
   858             private Entry(int index) {
   854                 this.index = index;
   859                 this.index = index;
   855             }
   860             }
   856 
   861 
       
   862             @SuppressWarnings("unchecked")
   857             public K getKey() {
   863             public K getKey() {
   858                 checkIndexForEntryUse();
   864                 checkIndexForEntryUse();
   859                 return (K) unmaskNull(traversalTable[index]);
   865                 return (K) unmaskNull(traversalTable[index]);
   860             }
   866             }
   861 
   867 
       
   868             @SuppressWarnings("unchecked")
   862             public V getValue() {
   869             public V getValue() {
   863                 checkIndexForEntryUse();
   870                 checkIndexForEntryUse();
   864                 return (V) traversalTable[index+1];
   871                 return (V) traversalTable[index+1];
   865             }
   872             }
   866 
   873 
       
   874             @SuppressWarnings("unchecked")
   867             public V setValue(V value) {
   875             public V setValue(V value) {
   868                 checkIndexForEntryUse();
   876                 checkIndexForEntryUse();
   869                 V oldValue = (V) traversalTable[index+1];
   877                 V oldValue = (V) traversalTable[index+1];
   870                 traversalTable[index+1] = value;
   878                 traversalTable[index+1] = value;
   871                 // if shadowing, force into main table
   879                 // if shadowing, force into main table
   878                 if (index < 0)
   886                 if (index < 0)
   879                     return super.equals(o);
   887                     return super.equals(o);
   880 
   888 
   881                 if (!(o instanceof Map.Entry))
   889                 if (!(o instanceof Map.Entry))
   882                     return false;
   890                     return false;
   883                 Map.Entry e = (Map.Entry)o;
   891                 Map.Entry<?,?> e = (Map.Entry<?,?>)o;
   884                 return (e.getKey() == unmaskNull(traversalTable[index]) &&
   892                 return (e.getKey() == unmaskNull(traversalTable[index]) &&
   885                        e.getValue() == traversalTable[index+1]);
   893                        e.getValue() == traversalTable[index+1]);
   886             }
   894             }
   887 
   895 
   888             public int hashCode() {
   896             public int hashCode() {
  1107             return new EntryIterator();
  1115             return new EntryIterator();
  1108         }
  1116         }
  1109         public boolean contains(Object o) {
  1117         public boolean contains(Object o) {
  1110             if (!(o instanceof Map.Entry))
  1118             if (!(o instanceof Map.Entry))
  1111                 return false;
  1119                 return false;
  1112             Map.Entry entry = (Map.Entry)o;
  1120             Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
  1113             return containsMapping(entry.getKey(), entry.getValue());
  1121             return containsMapping(entry.getKey(), entry.getValue());
  1114         }
  1122         }
  1115         public boolean remove(Object o) {
  1123         public boolean remove(Object o) {
  1116             if (!(o instanceof Map.Entry))
  1124             if (!(o instanceof Map.Entry))
  1117                 return false;
  1125                 return false;
  1118             Map.Entry entry = (Map.Entry)o;
  1126             Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
  1119             return removeMapping(entry.getKey(), entry.getValue());
  1127             return removeMapping(entry.getKey(), entry.getValue());
  1120         }
  1128         }
  1121         public int size() {
  1129         public int size() {
  1122             return size;
  1130             return size;
  1123         }
  1131         }
  1211         // Allow for 33% growth (i.e., capacity is >= 2* size()).
  1219         // Allow for 33% growth (i.e., capacity is >= 2* size()).
  1212         init(capacity((size*4)/3));
  1220         init(capacity((size*4)/3));
  1213 
  1221 
  1214         // Read the keys and values, and put the mappings in the table
  1222         // Read the keys and values, and put the mappings in the table
  1215         for (int i=0; i<size; i++) {
  1223         for (int i=0; i<size; i++) {
  1216             K key = (K) s.readObject();
  1224             @SuppressWarnings("unchecked")
  1217             V value = (V) s.readObject();
  1225                 K key = (K) s.readObject();
       
  1226             @SuppressWarnings("unchecked")
       
  1227                 V value = (V) s.readObject();
  1218             putForCreate(key, value);
  1228             putForCreate(key, value);
  1219         }
  1229         }
  1220     }
  1230     }
  1221 
  1231 
  1222     /**
  1232     /**
  1224      * update modCount, etc.
  1234      * update modCount, etc.
  1225      */
  1235      */
  1226     private void putForCreate(K key, V value)
  1236     private void putForCreate(K key, V value)
  1227         throws IOException
  1237         throws IOException
  1228     {
  1238     {
  1229         K k = (K)maskNull(key);
  1239         Object k = maskNull(key);
  1230         Object[] tab = table;
  1240         Object[] tab = table;
  1231         int len = tab.length;
  1241         int len = tab.length;
  1232         int i = hash(k, len);
  1242         int i = hash(k, len);
  1233 
  1243 
  1234         Object item;
  1244         Object item;