Created
March 20, 2015 02:06
-
-
Save ThomasLau/814a4093134a1a19510d to your computer and use it in GitHub Desktop.
pieces on writeObject and readobject methord in HashTable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Override | |
public synchronized V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { | |
Objects.requireNonNull(remappingFunction); | |
Entry<?,?> tab[] = table; | |
int hash = key.hashCode(); | |
int index = (hash & 0x7FFFFFFF) % tab.length; | |
@SuppressWarnings("unchecked") | |
Entry<K,V> e = (Entry<K,V>)tab[index]; | |
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) { | |
if (e.hash == hash && e.key.equals(key)) { | |
V newValue = remappingFunction.apply(e.value, value); | |
if (newValue == null) { | |
modCount++; | |
if (prev != null) { | |
prev.next = e.next; | |
} else { | |
tab[index] = e.next; | |
} | |
count--; | |
} else { | |
e.value = newValue; | |
} | |
return newValue; | |
} | |
} | |
if (value != null) { | |
addEntry(hash, key, value, index); | |
} | |
return value; | |
} | |
/** | |
* Save the state of the Hashtable to a stream (i.e., serialize it). | |
* | |
* @serialData The <i>capacity</i> of the Hashtable (the length of the | |
* bucket array) is emitted (int), followed by the | |
* <i>size</i> of the Hashtable (the number of key-value | |
* mappings), followed by the key (Object) and value (Object) | |
* for each key-value mapping represented by the Hashtable | |
* The key-value mappings are emitted in no particular order. | |
*/ | |
private void writeObject(java.io.ObjectOutputStream s) | |
throws IOException { | |
Entry<Object, Object> entryStack = null; | |
synchronized (this) { | |
// Write out the length, threshold, loadfactor | |
s.defaultWriteObject(); | |
// Write out length, count of elements | |
s.writeInt(table.length); | |
s.writeInt(count); | |
// Stack copies of the entries in the table | |
for (int index = 0; index < table.length; index++) { | |
Entry<?,?> entry = table[index]; | |
while (entry != null) { | |
entryStack = | |
new Entry<>(0, entry.key, entry.value, entryStack); | |
entry = entry.next; | |
} | |
} | |
} | |
// Write out the key/value objects from the stacked entries | |
while (entryStack != null) { | |
s.writeObject(entryStack.key); | |
s.writeObject(entryStack.value); | |
entryStack = entryStack.next; | |
} | |
} | |
/** | |
* Reconstitute the Hashtable from a stream (i.e., deserialize it). | |
*/ | |
private void readObject(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 | |
int origlength = s.readInt(); | |
int elements = 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. | |
int length = (int)(elements * loadFactor) + (elements / 20) + 3; | |
if (length > elements && (length & 1) == 0) | |
length--; | |
if (origlength > 0 && length > origlength) | |
length = origlength; | |
table = new Entry<?,?>[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") | |
K key = (K)s.readObject(); | |
@SuppressWarnings("unchecked") | |
V value = (V)s.readObject(); | |
// synch could be eliminated for performance | |
reconstitutionPut(table, key, value); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment