equal
deleted
inserted
replaced
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; |