publicbooleanequals(Object o) { if (o == this) returntrue;
if (!(o instanceof Map)) returnfalse; Map<?,?> m = (Map<?,?>) o; if (m.size() != size()) returnfalse;
try { Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) { Entry<K,V> e = i.next(); Kkey= e.getKey(); Vvalue= e.getValue(); if (value == null) { if (!(m.get(key)==null && m.containsKey(key))) returnfalse; } else { if (!value.equals(m.get(key))) returnfalse; } } } catch (ClassCastException unused) { returnfalse; } catch (NullPointerException unused) { returnfalse; }
returntrue; }
这里调用了m.get()而m即来自传入的o,此处的o若为LazyMap即可完成利用连
因此向上寻找
找到了Hashtable.reconstitutionPut()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
privatevoidreconstitutionPut(Entry<?,?>[] tab, K key, V value)throws StreamCorruptedException{ if (value == null) { thrownewjava.io.StreamCorruptedException(); } // Makes sure the key is not already in the hashtable. // This should not happen in deserialized version. inthash= key.hashCode(); intindex= (hash & 0x7FFFFFFF) % tab.length; for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { thrownewjava.io.StreamCorruptedException(); } } // Creates the new entry. @SuppressWarnings("unchecked") Entry<K,V> e = (Entry<K,V>)tab[index]; tab[index] = newEntry<>(hash, key, value, e); count++; }
privatevoidreadObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { // Read in the length, threshold, and loadfactor s.defaultReadObject();
// Read the original length of the array and number of elements intoriglength= s.readInt(); intelements= s.readInt();
// Compute new size with a bit of room 5% to grow but // no larger than the original size. Make the length // odd if it's large enough, this helps distribute the entries. // Guard against the length ending up zero, that's not valid. intlength= (int)(elements * loadFactor) + (elements / 20) + 3; if (length > elements && (length & 1) == 0) length--; if (origlength > 0 && length > origlength) length = origlength; table = newEntry<?,?>[length]; threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1); count = 0;
// Read the number of elements and then all the key/value objects for (; elements > 0; elements--) { @SuppressWarnings("unchecked") Kkey= (K)s.readObject(); @SuppressWarnings("unchecked") Vvalue= (V)s.readObject(); // synch could be eliminated for performance reconstitutionPut(table, key, value); } }
// Write out the key/value objects from the stacked entries while (entryStack != null) { s.writeObject(entryStack.key); s.writeObject(entryStack.value); entryStack = entryStack.next; } }
privatevoidreadObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { // Read in the length, threshold, and loadfactor s.defaultReadObject();
// Read the original length of the array and number of elements intoriglength= s.readInt(); intelements= s.readInt();
// Compute new size with a bit of room 5% to grow but // no larger than the original size. Make the length // odd if it's large enough, this helps distribute the entries. // Guard against the length ending up zero, that's not valid. intlength= (int)(elements * loadFactor) + (elements / 20) + 3; if (length > elements && (length & 1) == 0) length--; if (origlength > 0 && length > origlength) length = origlength; table = newEntry<?,?>[length]; threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1); count = 0;
// Read the number of elements and then all the key/value objects for (; elements > 0; elements--) { @SuppressWarnings("unchecked") Kkey= (K)s.readObject(); @SuppressWarnings("unchecked") Vvalue= (V)s.readObject(); // synch could be eliminated for performance reconstitutionPut(table, key, value); } }
privatevoidreconstitutionPut(Entry<?,?>[] tab, K key, V value) throws StreamCorruptedException { if (value == null) { thrownewjava.io.StreamCorruptedException(); } // Makes sure the key is not already in the hashtable. // This should not happen in deserialized version. inthash= key.hashCode(); intindex= (hash & 0x7FFFFFFF) % tab.length; for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { thrownewjava.io.StreamCorruptedException(); } } // Creates the new entry. @SuppressWarnings("unchecked") Entry<K,V> e = (Entry<K,V>)tab[index]; tab[index] = newEntry<>(hash, key, value, e); count++; }