213 */ 214 public Hashtable() { 215 this(11, 0.75f); 216 } 217 218 /** 219 * Constructs a new hashtable with the same mappings as the given 220 * Map. The hashtable is created with an initial capacity sufficient to 221 * hold the mappings in the given Map and a default load factor (0.75). 222 * 223 * @param t the map whose mappings are to be placed in this map. 224 * @throws NullPointerException if the specified map is null. 225 * @since 1.2 226 */ 227 public Hashtable(Map<? extends K, ? extends V> t) { 228 this(Math.max(2*t.size(), 11), 0.75f); 229 putAll(t); 230 } 231 232 /** 233 * Returns the number of keys in this hashtable. 234 * 235 * @return the number of keys in this hashtable. 236 */ 237 public synchronized int size() { 238 return count; 239 } 240 241 /** 242 * Tests if this hashtable maps no keys to values. 243 * 244 * @return <code>true</code> if this hashtable maps no keys to values; 245 * <code>false</code> otherwise. 246 */ 247 public synchronized boolean isEmpty() { 248 return count == 0; 249 } 250 251 /** 252 * Returns an enumeration of the keys in this hashtable. 532 533 /** 534 * Clears this hashtable so that it contains no keys. 535 */ 536 public synchronized void clear() { 537 Entry<?,?> tab[] = table; 538 for (int index = tab.length; --index >= 0; ) 539 tab[index] = null; 540 modCount++; 541 count = 0; 542 } 543 544 /** 545 * Creates a shallow copy of this hashtable. All the structure of the 546 * hashtable itself is copied, but the keys and values are not cloned. 547 * This is a relatively expensive operation. 548 * 549 * @return a clone of the hashtable 550 */ 551 public synchronized Object clone() { 552 try { 553 Hashtable<?,?> t = (Hashtable<?,?>)super.clone(); 554 t.table = new Entry<?,?>[table.length]; 555 for (int i = table.length ; i-- > 0 ; ) { 556 t.table[i] = (table[i] != null) 557 ? (Entry<?,?>) table[i].clone() : null; 558 } 559 t.keySet = null; 560 t.entrySet = null; 561 t.values = null; 562 t.modCount = 0; 563 return t; 564 } catch (CloneNotSupportedException e) { 565 // this shouldn't happen, since we are Cloneable 566 throw new InternalError(e); 567 } 568 } 569 570 /** 571 * Returns a string representation of this <tt>Hashtable</tt> object 572 * in the form of a set of entries, enclosed in braces and separated 573 * by the ASCII characters "<tt>, </tt>" (comma and space). Each 574 * entry is rendered as the key, an equals sign <tt>=</tt>, and the 575 * associated element, where the <tt>toString</tt> method is used to 576 * convert the key and element to strings. 577 * 578 * @return a string representation of this hashtable 579 */ 580 public synchronized String toString() { 581 int max = size() - 1; 582 if (max == -1) 583 return "{}"; 1172 1173 if (value != null) { 1174 addEntry(hash, key, value, index); 1175 } 1176 1177 return value; 1178 } 1179 1180 /** 1181 * Save the state of the Hashtable to a stream (i.e., serialize it). 1182 * 1183 * @serialData The <i>capacity</i> of the Hashtable (the length of the 1184 * bucket array) is emitted (int), followed by the 1185 * <i>size</i> of the Hashtable (the number of key-value 1186 * mappings), followed by the key (Object) and value (Object) 1187 * for each key-value mapping represented by the Hashtable 1188 * The key-value mappings are emitted in no particular order. 1189 */ 1190 private void writeObject(java.io.ObjectOutputStream s) 1191 throws IOException { 1192 Entry<Object, Object> entryStack = null; 1193 1194 synchronized (this) { 1195 // Write out the threshold and loadFactor 1196 s.defaultWriteObject(); 1197 1198 // Write out the length and count of elements 1199 s.writeInt(table.length); 1200 s.writeInt(count); 1201 1202 // Stack copies of the entries in the table 1203 for (Entry<?, ?> entry : table) { 1204 1205 while (entry != null) { 1206 entryStack = 1207 new Entry<>(0, entry.key, entry.value, entryStack); 1208 entry = entry.next; 1209 } 1210 } 1211 } 1212 1213 // Write out the key/value objects from the stacked entries 1214 while (entryStack != null) { 1215 s.writeObject(entryStack.key); 1216 s.writeObject(entryStack.value); 1217 entryStack = entryStack.next; 1218 } 1219 } 1220 1221 /** 1222 * Reconstitute the Hashtable from a stream (i.e., deserialize it). 1223 */ 1224 private void readObject(java.io.ObjectInputStream s) 1225 throws IOException, ClassNotFoundException 1226 { 1227 // Read in the threshold and loadFactor 1228 s.defaultReadObject(); 1229 1230 // Validate loadFactor (ignore threshold - it will be re-computed) 1231 if (loadFactor <= 0 || Float.isNaN(loadFactor)) 1232 throw new StreamCorruptedException("Illegal Load: " + loadFactor); 1233 1234 // Read the original length of the array and number of elements 1235 int origlength = s.readInt(); 1236 int elements = s.readInt(); 1237 1238 // Validate # of elements 1239 if (elements < 0) 1240 throw new StreamCorruptedException("Illegal # of Elements: " + elements); 1241 1242 // Clamp original length to be more than elements / loadFactor 1243 // (this is the invariant enforced with auto-growth) 1244 origlength = Math.max(origlength, (int)(elements / loadFactor) + 1); 1245 1246 // Compute new length with a bit of room 5% + 3 to grow but | 213 */ 214 public Hashtable() { 215 this(11, 0.75f); 216 } 217 218 /** 219 * Constructs a new hashtable with the same mappings as the given 220 * Map. The hashtable is created with an initial capacity sufficient to 221 * hold the mappings in the given Map and a default load factor (0.75). 222 * 223 * @param t the map whose mappings are to be placed in this map. 224 * @throws NullPointerException if the specified map is null. 225 * @since 1.2 226 */ 227 public Hashtable(Map<? extends K, ? extends V> t) { 228 this(Math.max(2*t.size(), 11), 0.75f); 229 putAll(t); 230 } 231 232 /** 233 * A constructor chained from {@link Properties} keeps Hashtable fields 234 * uninitialized since they are not used. 235 * 236 * @param dummy a dummy parameter 237 */ 238 Hashtable(Void dummy) {} 239 240 /** 241 * Returns the number of keys in this hashtable. 242 * 243 * @return the number of keys in this hashtable. 244 */ 245 public synchronized int size() { 246 return count; 247 } 248 249 /** 250 * Tests if this hashtable maps no keys to values. 251 * 252 * @return <code>true</code> if this hashtable maps no keys to values; 253 * <code>false</code> otherwise. 254 */ 255 public synchronized boolean isEmpty() { 256 return count == 0; 257 } 258 259 /** 260 * Returns an enumeration of the keys in this hashtable. 540 541 /** 542 * Clears this hashtable so that it contains no keys. 543 */ 544 public synchronized void clear() { 545 Entry<?,?> tab[] = table; 546 for (int index = tab.length; --index >= 0; ) 547 tab[index] = null; 548 modCount++; 549 count = 0; 550 } 551 552 /** 553 * Creates a shallow copy of this hashtable. All the structure of the 554 * hashtable itself is copied, but the keys and values are not cloned. 555 * This is a relatively expensive operation. 556 * 557 * @return a clone of the hashtable 558 */ 559 public synchronized Object clone() { 560 Hashtable<?,?> t = cloneHashtable(); 561 t.table = new Entry<?,?>[table.length]; 562 for (int i = table.length ; i-- > 0 ; ) { 563 t.table[i] = (table[i] != null) 564 ? (Entry<?,?>) table[i].clone() : null; 565 } 566 t.keySet = null; 567 t.entrySet = null; 568 t.values = null; 569 t.modCount = 0; 570 return t; 571 } 572 573 /** Calls super.clone() */ 574 final Hashtable<?,?> cloneHashtable() { 575 try { 576 return (Hashtable<?,?>)super.clone(); 577 } catch (CloneNotSupportedException e) { 578 // this shouldn't happen, since we are Cloneable 579 throw new InternalError(e); 580 } 581 } 582 583 /** 584 * Returns a string representation of this <tt>Hashtable</tt> object 585 * in the form of a set of entries, enclosed in braces and separated 586 * by the ASCII characters "<tt>, </tt>" (comma and space). Each 587 * entry is rendered as the key, an equals sign <tt>=</tt>, and the 588 * associated element, where the <tt>toString</tt> method is used to 589 * convert the key and element to strings. 590 * 591 * @return a string representation of this hashtable 592 */ 593 public synchronized String toString() { 594 int max = size() - 1; 595 if (max == -1) 596 return "{}"; 1185 1186 if (value != null) { 1187 addEntry(hash, key, value, index); 1188 } 1189 1190 return value; 1191 } 1192 1193 /** 1194 * Save the state of the Hashtable to a stream (i.e., serialize it). 1195 * 1196 * @serialData The <i>capacity</i> of the Hashtable (the length of the 1197 * bucket array) is emitted (int), followed by the 1198 * <i>size</i> of the Hashtable (the number of key-value 1199 * mappings), followed by the key (Object) and value (Object) 1200 * for each key-value mapping represented by the Hashtable 1201 * The key-value mappings are emitted in no particular order. 1202 */ 1203 private void writeObject(java.io.ObjectOutputStream s) 1204 throws IOException { 1205 writeHashtable(s); 1206 } 1207 1208 void writeHashtable(java.io.ObjectOutputStream s) 1209 throws IOException { 1210 Entry<Object, Object> entryStack = null; 1211 1212 synchronized (this) { 1213 // Write out the threshold and loadFactor 1214 s.defaultWriteObject(); 1215 1216 // Write out the length and count of elements 1217 s.writeInt(table.length); 1218 s.writeInt(count); 1219 1220 // Stack copies of the entries in the table 1221 for (Entry<?, ?> entry : table) { 1222 1223 while (entry != null) { 1224 entryStack = 1225 new Entry<>(0, entry.key, entry.value, entryStack); 1226 entry = entry.next; 1227 } 1228 } 1229 } 1230 1231 // Write out the key/value objects from the stacked entries 1232 while (entryStack != null) { 1233 s.writeObject(entryStack.key); 1234 s.writeObject(entryStack.value); 1235 entryStack = entryStack.next; 1236 } 1237 } 1238 1239 /** 1240 * Write out the simulated threshold, loadfactor 1241 * Called by Properties 1242 */ 1243 final void defaultWriteHashtable(java.io.ObjectOutputStream s, int length, 1244 float loadFactor) throws IOException { 1245 this.threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1); 1246 this.loadFactor = loadFactor; 1247 s.defaultWriteObject(); 1248 } 1249 1250 /** 1251 * Reconstitute the Hashtable from a stream (i.e., deserialize it). 1252 */ 1253 private void readObject(java.io.ObjectInputStream s) 1254 throws IOException, ClassNotFoundException { 1255 readHashtable(s); 1256 } 1257 1258 void readHashtable(java.io.ObjectInputStream s) 1259 throws IOException, ClassNotFoundException { 1260 // Read in the threshold and loadFactor 1261 s.defaultReadObject(); 1262 1263 // Validate loadFactor (ignore threshold - it will be re-computed) 1264 if (loadFactor <= 0 || Float.isNaN(loadFactor)) 1265 throw new StreamCorruptedException("Illegal Load: " + loadFactor); 1266 1267 // Read the original length of the array and number of elements 1268 int origlength = s.readInt(); 1269 int elements = s.readInt(); 1270 1271 // Validate # of elements 1272 if (elements < 0) 1273 throw new StreamCorruptedException("Illegal # of Elements: " + elements); 1274 1275 // Clamp original length to be more than elements / loadFactor 1276 // (this is the invariant enforced with auto-growth) 1277 origlength = Math.max(origlength, (int)(elements / loadFactor) + 1); 1278 1279 // Compute new length with a bit of room 5% + 3 to grow but |