Print this page


Split
Expand all
Collapse all
          --- old/src/share/classes/java/util/IdentityHashMap.java
          +++ new/src/share/classes/java/util/IdentityHashMap.java
↓ open down ↓ 319 lines elided ↑ open up ↑
 320  320       * {@code null}.  (There can be at most one such mapping.)
 321  321       *
 322  322       * <p>A return value of {@code null} does not <i>necessarily</i>
 323  323       * indicate that the map contains no mapping for the key; it's also
 324  324       * possible that the map explicitly maps the key to {@code null}.
 325  325       * The {@link #containsKey containsKey} operation may be used to
 326  326       * distinguish these two cases.
 327  327       *
 328  328       * @see #put(Object, Object)
 329  329       */
      330 +    @SuppressWarnings("unchecked")
 330  331      public V get(Object key) {
 331  332          Object k = maskNull(key);
 332  333          Object[] tab = table;
 333  334          int len = tab.length;
 334  335          int i = hash(k, len);
 335  336          while (true) {
 336  337              Object item = tab[i];
 337  338              if (item == k)
 338  339                  return (V) tab[i + 1];
 339  340              if (item == null)
↓ open down ↓ 84 lines elided ↑ open up ↑
 424  425       */
 425  426      public V put(K key, V value) {
 426  427          Object k = maskNull(key);
 427  428          Object[] tab = table;
 428  429          int len = tab.length;
 429  430          int i = hash(k, len);
 430  431  
 431  432          Object item;
 432  433          while ( (item = tab[i]) != null) {
 433  434              if (item == k) {
 434      -                V oldValue = (V) tab[i + 1];
      435 +                @SuppressWarnings("unchecked")
      436 +                    V oldValue = (V) tab[i + 1];
 435  437                  tab[i + 1] = value;
 436  438                  return oldValue;
 437  439              }
 438  440              i = nextKeyIndex(i, len);
 439  441          }
 440  442  
 441  443          modCount++;
 442  444          tab[i] = k;
 443  445          tab[i + 1] = value;
 444  446          if (++size >= threshold)
↓ open down ↓ 72 lines elided ↑ open up ↑
 517  519          Object k = maskNull(key);
 518  520          Object[] tab = table;
 519  521          int len = tab.length;
 520  522          int i = hash(k, len);
 521  523  
 522  524          while (true) {
 523  525              Object item = tab[i];
 524  526              if (item == k) {
 525  527                  modCount++;
 526  528                  size--;
 527      -                V oldValue = (V) tab[i + 1];
      529 +                @SuppressWarnings("unchecked")
      530 +                    V oldValue = (V) tab[i + 1];
 528  531                  tab[i + 1] = null;
 529  532                  tab[i] = null;
 530  533                  closeDeletion(i);
 531  534                  return oldValue;
 532  535              }
 533  536              if (item == null)
 534  537                  return null;
 535  538              i = nextKeyIndex(i, len);
 536  539          }
 537  540  
↓ open down ↓ 93 lines elided ↑ open up ↑
 631  634       * guaranteed to hold among <tt>IdentityHashMap</tt> instances.</b>
 632  635       *
 633  636       * @param  o object to be compared for equality with this map
 634  637       * @return <tt>true</tt> if the specified object is equal to this map
 635  638       * @see Object#equals(Object)
 636  639       */
 637  640      public boolean equals(Object o) {
 638  641          if (o == this) {
 639  642              return true;
 640  643          } else if (o instanceof IdentityHashMap) {
 641      -            IdentityHashMap m = (IdentityHashMap) o;
      644 +            IdentityHashMap<?,?> m = (IdentityHashMap<?,?>) o;
 642  645              if (m.size() != size)
 643  646                  return false;
 644  647  
 645  648              Object[] tab = m.table;
 646  649              for (int i = 0; i < tab.length; i+=2) {
 647  650                  Object k = tab[i];
 648  651                  if (k != null && !containsMapping(k, tab[i + 1]))
 649  652                      return false;
 650  653              }
 651  654              return true;
 652  655          } else if (o instanceof Map) {
 653      -            Map m = (Map)o;
      656 +            Map<?,?> m = (Map<?,?>)o;
 654  657              return entrySet().equals(m.entrySet());
 655  658          } else {
 656  659              return false;  // o is not a Map
 657  660          }
 658  661      }
 659  662  
 660  663      /**
 661  664       * Returns the hash code value for this map.  The hash code of a map is
 662  665       * defined to be the sum of the hash codes of each entry in the map's
 663  666       * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt>
↓ open down ↓ 27 lines elided ↑ open up ↑
 691  694      }
 692  695  
 693  696      /**
 694  697       * Returns a shallow copy of this identity hash map: the keys and values
 695  698       * themselves are not cloned.
 696  699       *
 697  700       * @return a shallow copy of this map
 698  701       */
 699  702      public Object clone() {
 700  703          try {
 701      -            IdentityHashMap<K,V> m = (IdentityHashMap<K,V>) super.clone();
      704 +            IdentityHashMap<?,?> m = (IdentityHashMap<?,?>) super.clone();
 702  705              m.entrySet = null;
 703  706              m.table = table.clone();
 704  707              return m;
 705  708          } catch (CloneNotSupportedException e) {
 706  709              throw new InternalError(e);
 707  710          }
 708  711      }
 709  712  
 710  713      private abstract class IdentityHashMapIterator<T> implements Iterator<T> {
 711  714          int index = (size != 0 ? 0 : table.length); // current slot.
↓ open down ↓ 49 lines elided ↑ open up ↑
 761  764              // when it does happen, we must make a copy of the rest of
 762  765              // the table to use for the rest of the traversal. Since
 763  766              // this can only happen when we are near the end of the table,
 764  767              // even in these rare cases, this is not very expensive in
 765  768              // time or space.
 766  769  
 767  770              Object[] tab = traversalTable;
 768  771              int len = tab.length;
 769  772  
 770  773              int d = deletedSlot;
 771      -            K key = (K) tab[d];
      774 +            Object key = tab[d];
 772  775              tab[d] = null;        // vacate the slot
 773  776              tab[d + 1] = null;
 774  777  
 775  778              // If traversing a copy, remove in real table.
 776  779              // We can skip gap-closure on copy.
 777  780              if (tab != IdentityHashMap.this.table) {
 778  781                  IdentityHashMap.this.remove(key);
 779  782                  expectedModCount = modCount;
 780  783                  return;
 781  784              }
↓ open down ↓ 29 lines elided ↑ open up ↑
 811  814                      tab[d + 1] = tab[i + 1];
 812  815                      tab[i] = null;
 813  816                      tab[i + 1] = null;
 814  817                      d = i;
 815  818                  }
 816  819              }
 817  820          }
 818  821      }
 819  822  
 820  823      private class KeyIterator extends IdentityHashMapIterator<K> {
      824 +        @SuppressWarnings("unchecked")
 821  825          public K next() {
 822  826              return (K) unmaskNull(traversalTable[nextIndex()]);
 823  827          }
 824  828      }
 825  829  
 826  830      private class ValueIterator extends IdentityHashMapIterator<V> {
      831 +        @SuppressWarnings("unchecked")
 827  832          public V next() {
 828  833              return (V) traversalTable[nextIndex() + 1];
 829  834          }
 830  835      }
 831  836  
 832  837      private class EntryIterator
 833  838          extends IdentityHashMapIterator<Map.Entry<K,V>>
 834  839      {
 835  840          private Entry lastReturnedEntry = null;
 836  841  
↓ open down ↓ 10 lines elided ↑ open up ↑
 847  852              lastReturnedEntry = null;
 848  853          }
 849  854  
 850  855          private class Entry implements Map.Entry<K,V> {
 851  856              private int index;
 852  857  
 853  858              private Entry(int index) {
 854  859                  this.index = index;
 855  860              }
 856  861  
      862 +            @SuppressWarnings("unchecked")
 857  863              public K getKey() {
 858  864                  checkIndexForEntryUse();
 859  865                  return (K) unmaskNull(traversalTable[index]);
 860  866              }
 861  867  
      868 +            @SuppressWarnings("unchecked")
 862  869              public V getValue() {
 863  870                  checkIndexForEntryUse();
 864  871                  return (V) traversalTable[index+1];
 865  872              }
 866  873  
      874 +            @SuppressWarnings("unchecked")
 867  875              public V setValue(V value) {
 868  876                  checkIndexForEntryUse();
 869  877                  V oldValue = (V) traversalTable[index+1];
 870  878                  traversalTable[index+1] = value;
 871  879                  // if shadowing, force into main table
 872  880                  if (traversalTable != IdentityHashMap.this.table)
 873  881                      put((K) traversalTable[index], value);
 874  882                  return oldValue;
 875  883              }
 876  884  
 877  885              public boolean equals(Object o) {
 878  886                  if (index < 0)
 879  887                      return super.equals(o);
 880  888  
 881  889                  if (!(o instanceof Map.Entry))
 882  890                      return false;
 883      -                Map.Entry e = (Map.Entry)o;
      891 +                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
 884  892                  return (e.getKey() == unmaskNull(traversalTable[index]) &&
 885  893                         e.getValue() == traversalTable[index+1]);
 886  894              }
 887  895  
 888  896              public int hashCode() {
 889  897                  if (lastReturnedIndex < 0)
 890  898                      return super.hashCode();
 891  899  
 892  900                  return (System.identityHashCode(unmaskNull(traversalTable[index])) ^
 893  901                         System.identityHashCode(traversalTable[index+1]));
↓ open down ↓ 208 lines elided ↑ open up ↑
1102 1110              return entrySet = new EntrySet();
1103 1111      }
1104 1112  
1105 1113      private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
1106 1114          public Iterator<Map.Entry<K,V>> iterator() {
1107 1115              return new EntryIterator();
1108 1116          }
1109 1117          public boolean contains(Object o) {
1110 1118              if (!(o instanceof Map.Entry))
1111 1119                  return false;
1112      -            Map.Entry entry = (Map.Entry)o;
     1120 +            Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
1113 1121              return containsMapping(entry.getKey(), entry.getValue());
1114 1122          }
1115 1123          public boolean remove(Object o) {
1116 1124              if (!(o instanceof Map.Entry))
1117 1125                  return false;
1118      -            Map.Entry entry = (Map.Entry)o;
     1126 +            Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
1119 1127              return removeMapping(entry.getKey(), entry.getValue());
1120 1128          }
1121 1129          public int size() {
1122 1130              return size;
1123 1131          }
1124 1132          public void clear() {
1125 1133              IdentityHashMap.this.clear();
1126 1134          }
1127 1135          /*
1128 1136           * Must revert from AbstractSet's impl to AbstractCollection's, as
↓ open down ↓ 77 lines elided ↑ open up ↑
1206 1214          s.defaultReadObject();
1207 1215  
1208 1216          // Read in size (number of Mappings)
1209 1217          int size = s.readInt();
1210 1218  
1211 1219          // Allow for 33% growth (i.e., capacity is >= 2* size()).
1212 1220          init(capacity((size*4)/3));
1213 1221  
1214 1222          // Read the keys and values, and put the mappings in the table
1215 1223          for (int i=0; i<size; i++) {
1216      -            K key = (K) s.readObject();
1217      -            V value = (V) s.readObject();
     1224 +            @SuppressWarnings("unchecked")
     1225 +                K key = (K) s.readObject();
     1226 +            @SuppressWarnings("unchecked")
     1227 +                V value = (V) s.readObject();
1218 1228              putForCreate(key, value);
1219 1229          }
1220 1230      }
1221 1231  
1222 1232      /**
1223 1233       * The put method for readObject.  It does not resize the table,
1224 1234       * update modCount, etc.
1225 1235       */
1226 1236      private void putForCreate(K key, V value)
1227 1237          throws IOException
1228 1238      {
1229      -        K k = (K)maskNull(key);
     1239 +        Object k = maskNull(key);
1230 1240          Object[] tab = table;
1231 1241          int len = tab.length;
1232 1242          int i = hash(k, len);
1233 1243  
1234 1244          Object item;
1235 1245          while ( (item = tab[i]) != null) {
1236 1246              if (item == k)
1237 1247                  throw new java.io.StreamCorruptedException();
1238 1248              i = nextKeyIndex(i, len);
1239 1249          }
1240 1250          tab[i] = k;
1241 1251          tab[i + 1] = value;
1242 1252      }
1243 1253  }