HashtableTest.java revision 561ee011997c6c2f1befbfaa9d5f0a99771c1d63
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.luni.tests.java.util;
19
20import java.util.ArrayList;
21import java.util.Arrays;
22import java.util.Collection;
23import java.util.ConcurrentModificationException;
24import java.util.Enumeration;
25import java.util.HashSet;
26import java.util.Hashtable;
27import java.util.Iterator;
28import java.util.Map;
29import java.util.NoSuchElementException;
30import java.util.Set;
31import java.util.TreeMap;
32import java.util.Vector;
33
34import tests.support.Support_MapTest2;
35import tests.support.Support_UnmodifiableCollectionTest;
36
37public class HashtableTest extends junit.framework.TestCase {
38
39	private Hashtable ht10;
40
41	private Hashtable ht100;
42
43	private Hashtable htfull;
44
45	private Vector keyVector;
46
47	private Vector elmVector;
48
49	private String h10sVal;
50
51	/**
52	 * @tests java.util.Hashtable#Hashtable()
53	 */
54	public void test_Constructor() {
55		// Test for method java.util.Hashtable()
56		new Support_MapTest2(new Hashtable()).runTest();
57
58		Hashtable h = new Hashtable();
59
60		assertEquals("Created incorrect hashtable", 0, h.size());
61	}
62
63	/**
64	 * @tests java.util.Hashtable#Hashtable(int)
65	 */
66	public void test_ConstructorI() {
67		// Test for method java.util.Hashtable(int)
68		Hashtable h = new Hashtable(9);
69
70		assertEquals("Created incorrect hashtable", 0, h.size());
71
72		Hashtable empty = new Hashtable(0);
73		assertNull("Empty hashtable access", empty.get("nothing"));
74		empty.put("something", "here");
75		assertTrue("cannot get element", empty.get("something") == "here");
76	}
77
78	/**
79	 * @tests java.util.Hashtable#Hashtable(int, float)
80	 */
81	public void test_ConstructorIF() {
82		// Test for method java.util.Hashtable(int, float)
83		Hashtable h = new java.util.Hashtable(10, 0.5f);
84		assertEquals("Created incorrect hashtable", 0, h.size());
85
86		Hashtable empty = new Hashtable(0, 0.75f);
87		assertNull("Empty hashtable access", empty.get("nothing"));
88		empty.put("something", "here");
89		assertTrue("cannot get element", empty.get("something") == "here");
90	}
91
92	/**
93	 * @tests java.util.Hashtable#Hashtable(java.util.Map)
94	 */
95	public void test_ConstructorLjava_util_Map() {
96		// Test for method java.util.Hashtable(java.util.Map)
97		Map map = new TreeMap();
98		Object firstVal = "Gabba";
99		Object secondVal = new Integer(5);
100		map.put("Gah", firstVal);
101		map.put("Ooga", secondVal);
102		Hashtable ht = new Hashtable(map);
103		assertTrue("a) Incorrect Hashtable constructed",
104				ht.get("Gah") == firstVal);
105		assertTrue("b) Incorrect Hashtable constructed",
106				ht.get("Ooga") == secondVal);
107	}
108
109    public void test_HashTable_Constructor() {
110        Hashtable hashTable = new Hashtable();
111        hashTable.put(hashTable, hashTable.keySet());
112        new Hashtable(hashTable);
113    }
114
115	/**
116	 * @tests java.util.Hashtable#clear()
117	 */
118	public void test_clear() {
119		// Test for method void java.util.Hashtable.clear()
120		Hashtable h = hashtableClone(htfull);
121		h.clear();
122		assertEquals("Hashtable was not cleared", 0, h.size());
123		Enumeration el = h.elements();
124		Enumeration keys = h.keys();
125		assertTrue("Hashtable improperly cleared", !el.hasMoreElements()
126				&& !(keys.hasMoreElements()));
127	}
128
129	/**
130	 * @tests java.util.Hashtable#clone()
131	 */
132	public void test_clone() {
133		// Test for method java.lang.Object java.util.Hashtable.clone()
134
135		Hashtable h = (Hashtable) htfull.clone();
136		assertTrue("Clone different size than original", h.size() == htfull
137				.size());
138
139		Enumeration org = htfull.keys();
140		Enumeration cpy = h.keys();
141
142		String okey, ckey;
143		while (org.hasMoreElements()) {
144			assertTrue("Key comparison failed", (okey = (String) org
145					.nextElement()).equals(ckey = (String) cpy.nextElement()));
146			assertTrue("Value comparison failed", ((String) htfull.get(okey))
147					.equals((String) h.get(ckey)));
148		}
149		assertTrue("Copy has more keys than original", !cpy.hasMoreElements());
150	}
151
152	/**
153	 * @tests java.util.Hashtable#contains(java.lang.Object)
154	 */
155	public void test_containsLjava_lang_Object() {
156		// Test for method boolean
157		// java.util.Hashtable.contains(java.lang.Object)
158		assertTrue("Element not found", ht10.contains("Val 7"));
159		assertTrue("Invalid element found", !ht10.contains("ZZZZZZZZZZZZZZZZ"));
160	}
161
162	/**
163	 * @tests java.util.Hashtable#containsKey(java.lang.Object)
164	 */
165	public void test_containsKeyLjava_lang_Object() {
166		// Test for method boolean
167		// java.util.Hashtable.containsKey(java.lang.Object)
168
169		assertTrue("Failed to find key", htfull.containsKey("FKey 4"));
170		assertTrue("Failed to find key", !htfull.containsKey("FKey 99"));
171	}
172
173	/**
174	 * @tests java.util.Hashtable#containsValue(java.lang.Object)
175	 */
176	public void test_containsValueLjava_lang_Object() {
177		// Test for method boolean
178		// java.util.Hashtable.containsValue(java.lang.Object)
179		Enumeration e = elmVector.elements();
180		while (e.hasMoreElements())
181			assertTrue("Returned false for valid value", ht10.containsValue(e
182					.nextElement()));
183		assertTrue("Returned true for invalid value", !ht10
184				.containsValue(new Object()));
185	}
186
187	/**
188	 * @tests java.util.Hashtable#elements()
189	 */
190	public void test_elements() {
191		// Test for method java.util.Enumeration java.util.Hashtable.elements()
192		Enumeration elms = ht10.elements();
193		int i = 0;
194		while (elms.hasMoreElements()) {
195			String s = (String) elms.nextElement();
196			assertTrue("Missing key from enumeration", elmVector.contains(s));
197			++i;
198		}
199
200		assertEquals("All keys not retrieved", 10, ht10.size());
201
202        // cast Enumeration to Iterator
203        Iterator iterator = (Iterator) elms;
204        assertFalse(iterator.hasNext());
205        try {
206            iterator.next();
207            fail("should throw NoSuchElementException");
208        } catch (NoSuchElementException e) {
209            // Expected
210        }
211	}
212
213	/**
214	 * @tests java.util.Hashtable#elements()
215	 */
216	public void test_elements_subtest0() {
217		// this is the reference implementation behavior
218		final Hashtable ht = new Hashtable(7);
219		ht.put("1", "a");
220		// these three elements hash to the same bucket in a 7 element Hashtable
221		ht.put("2", "b");
222		ht.put("9", "c");
223		ht.put("12", "d");
224		// Hashtable looks like:
225		// 0: "1"
226		// 1: "12" -> "9" -> "2"
227		Enumeration en = ht.elements();
228		// cache the first entry
229		en.hasMoreElements();
230		ht.remove("12");
231		ht.remove("9");
232		boolean exception = false;
233		try {
234			// cached "12"
235			Object result = en.nextElement();
236			assertNull("unexpected: " + result, result);
237			// next is removed "9"
238			result = en.nextElement();
239			assertNull("unexpected: " + result, result);
240			result = en.nextElement();
241			assertTrue("unexpected: " + result, "b".equals(result));
242		} catch (NoSuchElementException e) {
243			exception = true;
244		}
245		assertTrue("unexpected NoSuchElementException", !exception);
246	}
247
248	/**
249	 * @tests java.util.Hashtable#entrySet()
250	 */
251	public void test_entrySet() {
252		// Test for method java.util.Set java.util.Hashtable.entrySet()
253		Set s = ht10.entrySet();
254		Set s2 = new HashSet();
255		Iterator i = s.iterator();
256		while (i.hasNext())
257			s2.add(((Map.Entry) i.next()).getValue());
258		Enumeration e = elmVector.elements();
259		while (e.hasMoreElements())
260			assertTrue("Returned incorrect entry set", s2.contains(e
261					.nextElement()));
262
263		assertEquals("Not synchronized",
264				"java.util.Collections$SynchronizedSet", s.getClass().getName());
265
266		boolean exception = false;
267		try {
268			((Map.Entry) ht10.entrySet().iterator().next()).setValue(null);
269		} catch (NullPointerException e1) {
270			exception = true;
271		}
272		assertTrue(
273				"Should not be able to assign null to a Hashtable entrySet() Map.Entry",
274				exception);
275	}
276
277	/**
278	 * @tests java.util.Hashtable#equals(java.lang.Object)
279	 */
280	public void test_equalsLjava_lang_Object() {
281		// Test for method boolean java.util.Hashtable.equals(java.lang.Object)
282		Hashtable h = hashtableClone(ht10);
283		assertTrue("Returned false for equal tables", ht10.equals(h));
284		assertTrue("Returned true for unequal tables", !ht10.equals(htfull));
285	}
286
287	/**
288	 * @tests java.util.Hashtable#get(java.lang.Object)
289	 */
290	public void test_getLjava_lang_Object() {
291		// Test for method java.lang.Object
292		// java.util.Hashtable.get(java.lang.Object)
293		Hashtable h = hashtableClone(htfull);
294		assertEquals("Could not retrieve element", "FVal 2", ((String) h.get("FKey 2"))
295				);
296
297
298		// Regression for HARMONY-262
299		ReusableKey k = new ReusableKey();
300		Hashtable h2 = new Hashtable();
301		k.setKey(1);
302		h2.put(k, "value1");
303
304		k.setKey(13);
305		assertNull(h2.get(k));
306
307		k.setKey(12);
308		assertNull(h2.get(k));
309	}
310
311	/**
312	 * @tests java.util.Hashtable#hashCode()
313	 */
314	public void test_hashCode() {
315		// Test for method int java.util.Hashtable.hashCode()
316		Set entrySet = ht10.entrySet();
317		Iterator iterator = entrySet.iterator();
318		int expectedHash;
319		for (expectedHash = 0; iterator.hasNext(); expectedHash += iterator
320				.next().hashCode())
321			;
322		assertTrue("Incorrect hashCode returned.  Wanted: " + expectedHash
323				+ " got: " + ht10.hashCode(), expectedHash == ht10.hashCode());
324	}
325
326	/**
327	 * @tests java.util.Hashtable#isEmpty()
328	 */
329	public void test_isEmpty() {
330		// Test for method boolean java.util.Hashtable.isEmpty()
331
332		assertTrue("isEmpty returned incorrect value", !ht10.isEmpty());
333		assertTrue("isEmpty returned incorrect value",
334				new java.util.Hashtable().isEmpty());
335
336		final Hashtable ht = new Hashtable();
337		ht.put("0", "");
338		Thread t1 = new Thread() {
339			public void run() {
340				while (!ht.isEmpty())
341					;
342				ht.put("final", "");
343			}
344		};
345		t1.start();
346		for (int i = 1; i < 10000; i++) {
347			synchronized (ht) {
348				ht.remove(String.valueOf(i - 1));
349				ht.put(String.valueOf(i), "");
350			}
351			int size;
352			if ((size = ht.size()) != 1) {
353				String result = "Size is not 1: " + size + " " + ht;
354				// terminate the thread
355				ht.clear();
356				fail(result);
357			}
358		}
359		// terminate the thread
360		ht.clear();
361	}
362
363	/**
364	 * @tests java.util.Hashtable#keys()
365	 */
366	public void test_keys() {
367		// Test for method java.util.Enumeration java.util.Hashtable.keys()
368
369		Enumeration keys = ht10.keys();
370		int i = 0;
371		while (keys.hasMoreElements()) {
372			String s = (String) keys.nextElement();
373			assertTrue("Missing key from enumeration", keyVector.contains(s));
374			++i;
375		}
376
377		assertEquals("All keys not retrieved", 10, ht10.size());
378
379        // cast Enumeration to Iterator
380        Iterator iterator = (Iterator) keys;
381        assertFalse(iterator.hasNext());
382        try {
383            iterator.next();
384            fail("should throw NoSuchElementException");
385        } catch (NoSuchElementException e) {
386            // Expected
387        }
388	}
389
390	/**
391	 * @tests java.util.Hashtable#keys()
392	 */
393	public void test_keys_subtest0() {
394		// this is the reference implementation behavior
395		final Hashtable ht = new Hashtable(3);
396		ht.put("initial", "");
397		Enumeration en = ht.keys();
398		en.hasMoreElements();
399		ht.remove("initial");
400		boolean exception = false;
401		try {
402			Object result = en.nextElement();
403			assertTrue("unexpected: " + result, "initial".equals(result));
404		} catch (NoSuchElementException e) {
405			exception = true;
406		}
407		assertTrue("unexpected NoSuchElementException", !exception);
408	}
409
410	/**
411	 * @tests java.util.Hashtable#keySet()
412	 */
413	public void test_keySet() {
414		// Test for method java.util.Set java.util.Hashtable.keySet()
415		Set s = ht10.keySet();
416		Enumeration e = keyVector.elements();
417		while (e.hasMoreElements())
418			assertTrue("Returned incorrect key set", s
419					.contains(e.nextElement()));
420
421		assertEquals("Not synchronized",
422				"java.util.Collections$SynchronizedSet", s.getClass().getName());
423
424		Map map = new Hashtable(101);
425		map.put(new Integer(1), "1");
426		map.put(new Integer(102), "102");
427		map.put(new Integer(203), "203");
428		Iterator it = map.keySet().iterator();
429		Integer remove1 = (Integer) it.next();
430		it.remove();
431		Integer remove2 = (Integer) it.next();
432		it.remove();
433		ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
434				new Integer(1), new Integer(102), new Integer(203) }));
435		list.remove(remove1);
436		list.remove(remove2);
437		assertTrue("Wrong result", it.next().equals(list.get(0)));
438		assertEquals("Wrong size", 1, map.size());
439		assertTrue("Wrong contents", map.keySet().iterator().next().equals(
440				list.get(0)));
441
442		Map map2 = new Hashtable(101);
443		map2.put(new Integer(1), "1");
444		map2.put(new Integer(4), "4");
445		Iterator it2 = map2.keySet().iterator();
446		Integer remove3 = (Integer) it2.next();
447		Integer next;
448		if (remove3.intValue() == 1)
449			next = new Integer(4);
450		else
451			next = new Integer(1);
452		it2.hasNext();
453		it2.remove();
454		assertTrue("Wrong result 2", it2.next().equals(next));
455		assertEquals("Wrong size 2", 1, map2.size());
456		assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
457				next));
458
459        // cast Iterator to Enumeration
460        Enumeration enumeration = (Enumeration) s.iterator();
461        assertTrue(enumeration.hasMoreElements());
462	}
463
464	/**
465	 * @tests java.util.Hashtable#keySet()
466	 */
467	public void test_keySet_subtest0() {
468		Set s1 = ht10.keySet();
469		assertTrue("should contain key", s1.remove("Key 0"));
470		assertTrue("should not contain key", !s1.remove("Key 0"));
471
472		final int iterations = 10000;
473		final Hashtable ht = new Hashtable();
474		Thread t1 = new Thread() {
475			public void run() {
476				for (int i = 0; i < iterations; i++) {
477					ht.put(String.valueOf(i), "");
478					ht.remove(String.valueOf(i));
479				}
480			}
481		};
482		t1.start();
483		Set set = ht.keySet();
484		for (int i = 0; i < iterations; i++) {
485			Iterator it = set.iterator();
486			try {
487				it.next();
488				it.remove();
489				int size;
490				// ensure removing with the iterator doesn't corrupt the
491				// Hashtable
492				if ((size = ht.size()) < 0) {
493					fail("invalid size: " + size);
494				}
495			} catch (NoSuchElementException e) {
496			} catch (ConcurrentModificationException e) {
497			}
498		}
499	}
500
501	/**
502	 * @tests java.util.Hashtable#keySet()
503	 */
504	public void test_keySet_subtest1() {
505		// this is the reference implementation behavior
506		final Hashtable ht = new Hashtable(7);
507		ht.put("1", "a");
508		// these three elements hash to the same bucket in a 7 element Hashtable
509		ht.put("2", "b");
510		ht.put("9", "c");
511		ht.put("12", "d");
512		// Hashtable looks like:
513		// 0: "1"
514		// 1: "12" -> "9" -> "2"
515		Enumeration en = ht.elements();
516		// cache the first entry
517		en.hasMoreElements();
518		Iterator it = ht.keySet().iterator();
519		// this is mostly a copy of the test in test_elements_subtest0()
520		// test removing with the iterator does not null the values
521		while (it.hasNext()) {
522			String key = (String) it.next();
523			if ("12".equals(key) || "9".equals(key)) {
524				it.remove();
525			}
526		}
527		it.remove();
528		boolean exception = false;
529		try {
530			// cached "12"
531			Object result = en.nextElement();
532			assertTrue("unexpected: " + result, "d".equals(result));
533			// next is removed "9"
534			result = en.nextElement();
535			assertTrue("unexpected: " + result, "c".equals(result));
536			result = en.nextElement();
537			assertTrue("unexpected: " + result, "b".equals(result));
538		} catch (NoSuchElementException e) {
539			exception = true;
540		}
541		assertTrue("unexpected NoSuchElementException", !exception);
542	}
543
544	/**
545	 * @tests java.util.Hashtable#put(java.lang.Object, java.lang.Object)
546	 */
547	public void test_putLjava_lang_ObjectLjava_lang_Object() {
548		// Test for method java.lang.Object
549		// java.util.Hashtable.put(java.lang.Object, java.lang.Object)
550		Hashtable h = hashtableClone(ht100);
551		Integer key = new Integer(100);
552		h.put("Value 100", key);
553		assertTrue("Key/Value not inserted", h.size() == 1 && (h.contains(key)));
554
555		// Put into "full" table
556		h = hashtableClone(htfull);
557		h.put("Value 100", key);
558		assertTrue("Key/Value not inserted into full table", h.size() == 8
559				&& (h.contains(key)));
560	}
561
562	/**
563	 * @tests java.util.Hashtable#putAll(java.util.Map)
564	 */
565	public void test_putAllLjava_util_Map() {
566		// Test for method void java.util.Hashtable.putAll(java.util.Map)
567		Hashtable h = new Hashtable();
568		h.putAll(ht10);
569		Enumeration e = keyVector.elements();
570		while (e.hasMoreElements()) {
571			Object x = e.nextElement();
572			assertTrue("Failed to put all elements", h.get(x).equals(
573					ht10.get(x)));
574		}
575	}
576
577	/**
578	 * @tests java.util.Hashtable#remove(java.lang.Object)
579	 */
580	public void test_removeLjava_lang_Object() {
581		// Test for method java.lang.Object
582		// java.util.Hashtable.remove(java.lang.Object)
583		Hashtable h = hashtableClone(htfull);
584		Object k = h.remove("FKey 0");
585		assertTrue("Remove failed", !h.containsKey("FKey 0") || k == null);
586	}
587
588    public void test_HashTable_remove_scenario1() {
589        Hashtable hashTable = new Hashtable();
590        Set keySet = hashTable.keySet();
591        hashTable.put(hashTable, keySet);
592        hashTable.remove(hashTable);
593    }
594
595    public void test_HashTable_remove_scenario2() {
596        Hashtable hashTable = new Hashtable();
597        Set keySet = hashTable.keySet();
598        hashTable.put(hashTable, hashTable);
599        hashTable.remove(hashTable);
600    }
601
602    public void test_HashTable_remove_scenario3() {
603        Hashtable hashTable = new Hashtable();
604        Hashtable keyHashTable = new Hashtable();
605        keyHashTable.put(hashTable, keyHashTable);
606        hashTable.put(keyHashTable, hashTable);
607        hashTable.remove(keyHashTable);
608    }
609
610	/**
611	 * @tests java.util.Hashtable#size()
612	 */
613	public void test_size() {
614		// Test for method int java.util.Hashtable.size()
615		assertTrue("Returned invalid size", ht10.size() == 10
616				&& (ht100.size() == 0));
617
618		final Hashtable ht = new Hashtable();
619		ht.put("0", "");
620		Thread t1 = new Thread() {
621			public void run() {
622				while (ht.size() > 0)
623					;
624				ht.put("final", "");
625			}
626		};
627		t1.start();
628		for (int i = 1; i < 10000; i++) {
629			synchronized (ht) {
630				ht.remove(String.valueOf(i - 1));
631				ht.put(String.valueOf(i), "");
632			}
633			int size;
634			if ((size = ht.size()) != 1) {
635				String result = "Size is not 1: " + size + " " + ht;
636				// terminate the thread
637				ht.clear();
638				fail(result);
639			}
640		}
641		// terminate the thread
642		ht.clear();
643	}
644
645	/**
646	 * @tests java.util.Hashtable#toString()
647	 */
648	public void test_toString() {
649		// Test for method java.lang.String java.util.Hashtable.toString()
650		Hashtable h = new Hashtable();
651		assertEquals("Incorrect toString for Empty table",
652				"{}", h.toString());
653
654		h.put("one", "1");
655		h.put("two", h);
656		h.put(h, "3");
657		h.put(h, h);
658		String result = h.toString();
659		assertTrue("should contain self ref", result.indexOf("(this") > -1);
660	}
661
662	/**
663	 * @tests java.util.Hashtable#values()
664	 */
665	public void test_values() {
666		// Test for method java.util.Collection java.util.Hashtable.values()
667		Collection c = ht10.values();
668		Enumeration e = elmVector.elements();
669		while (e.hasMoreElements())
670			assertTrue("Returned incorrect values", c.contains(e.nextElement()));
671
672		assertEquals("Not synchronized",
673				"java.util.Collections$SynchronizedCollection", c.getClass().getName());
674
675		Hashtable myHashtable = new Hashtable();
676		for (int i = 0; i < 100; i++)
677			myHashtable.put(new Integer(i), new Integer(i));
678		Collection values = myHashtable.values();
679		new Support_UnmodifiableCollectionTest(
680				"Test Returned Collection From Hashtable.values()", values)
681				.runTest();
682		values.remove(new Integer(0));
683		assertTrue(
684				"Removing from the values collection should remove from the original map",
685				!myHashtable.containsValue(new Integer(0)));
686	}
687
688    /**
689     * Regression Test for JIRA 2181
690     */
691    public void test_entrySet_remove()
692    {
693        Hashtable<String,String> hashtable = new Hashtable<String,String>();
694        hashtable.put("my.nonexistent.prop", "AAA");
695        hashtable.put( "parse.error", "BBB" );
696        Iterator<Map.Entry<String,String>> iterator =
697            hashtable.entrySet().iterator();
698        while(iterator.hasNext())
699        {
700            Map.Entry entry = iterator.next();
701            final Object value = entry.getValue();
702            if(value.equals("AAA"))
703            {
704               iterator.remove();
705            }
706        }
707        assertFalse(hashtable.containsKey("my.nonexistent.prop"));
708    }
709
710    /**
711     * @tests java.util.Hashtable#elements()
712     * @tests java.util.Hashtable#keys()
713     * @tests java.util.Hashtable#keySet()
714     */
715    public void test_keys_elements_keySet_Exceptions() {
716        Hashtable hashTable = new Hashtable();
717        String key = "key";
718        String value = "value";
719        hashTable.put(key, value);
720
721        Iterator iterator = (Iterator) hashTable.keys();
722        assertTrue(iterator.hasNext());
723        try {
724            iterator.remove();
725            fail("should throw UnsupportedOperationException");
726        } catch (UnsupportedOperationException e) {
727            // Expected
728        }
729        iterator.next();
730        try {
731            iterator.remove();
732            fail("should throw UnsupportedOperationException");
733        } catch (UnsupportedOperationException e) {
734            // Expected
735        }
736        assertFalse(iterator.hasNext());
737
738        iterator = (Iterator) hashTable.elements();
739        assertTrue(iterator.hasNext());
740        try {
741            iterator.remove();
742            fail("should throw UnsupportedOperationException");
743        } catch (UnsupportedOperationException e) {
744            // Expected
745        }
746        iterator.next();
747        try {
748            iterator.remove();
749            fail("should throw UnsupportedOperationException");
750        } catch (UnsupportedOperationException e) {
751            // Expected
752        }
753        assertFalse(iterator.hasNext());
754
755        iterator = hashTable.keySet().iterator();
756        assertTrue(iterator.hasNext());
757        try {
758            iterator.remove();
759            fail("should throw IllegalStateException");
760        } catch (IllegalStateException e) {
761            // Expected
762        }
763        iterator.next();
764        iterator.remove();
765        assertFalse(iterator.hasNext());
766
767        hashTable.clear();
768        for (int i = 0; i < 10; i++) {
769            hashTable.put(key + i, value + i);
770        }
771
772        // cast Enumeration to Iterator
773        Enumeration enumeration = hashTable.keys();
774        iterator = (Iterator) enumeration;
775        assertTrue(enumeration.hasMoreElements());
776        assertTrue(iterator.hasNext());
777        for (int i = 0; i < 10; i++) {
778            if (i % 2 == 0) {
779                enumeration.nextElement();
780            } else {
781                iterator.next();
782            }
783        }
784        assertFalse(enumeration.hasMoreElements());
785        assertFalse(iterator.hasNext());
786        try {
787            enumeration.nextElement();
788            fail("should throw NoSuchElementException");
789        } catch (NoSuchElementException e) {
790            // Expected
791        }
792        try {
793            iterator.next();
794            fail("should throw NoSuchElementException");
795        } catch (NoSuchElementException e) {
796            // Expected
797        }
798
799        // cast Enumeration to Iterator
800        enumeration = hashTable.elements();
801        iterator = (Iterator) enumeration;
802        assertTrue(enumeration.hasMoreElements());
803        assertTrue(iterator.hasNext());
804        for (int i = 0; i < 10; i++) {
805            if (i % 2 == 0) {
806                enumeration.nextElement();
807            } else {
808                iterator.next();
809            }
810        }
811        assertFalse(enumeration.hasMoreElements());
812        assertFalse(iterator.hasNext());
813        try {
814            enumeration.nextElement();
815            fail("should throw NoSuchElementException");
816        } catch (NoSuchElementException e) {
817            // Expected
818        }
819        try {
820            iterator.next();
821            fail("should throw NoSuchElementException");
822        } catch (NoSuchElementException e) {
823            // Expected
824        }
825
826        // cast Iterator to Enumeration
827        enumeration = (Enumeration) hashTable.keySet().iterator();
828        iterator = (Iterator) enumeration;
829        assertTrue(enumeration.hasMoreElements());
830        assertTrue(iterator.hasNext());
831        for (int i = 0; i < 10; i++) {
832            if (i % 2 == 0) {
833                enumeration.nextElement();
834            } else {
835                iterator.next();
836            }
837        }
838        assertFalse(enumeration.hasMoreElements());
839        assertFalse(iterator.hasNext());
840        try {
841            enumeration.nextElement();
842            fail("should throw NoSuchElementException");
843        } catch (NoSuchElementException e) {
844            // Expected
845        }
846        try {
847            iterator.next();
848            fail("should throw NoSuchElementException");
849        } catch (NoSuchElementException e) {
850            // Expected
851        }
852    }
853
854	protected Hashtable hashtableClone(Hashtable s) {
855		return (Hashtable) s.clone();
856	}
857
858	/**
859	 * Sets up the fixture, for example, open a network connection. This method
860	 * is called before a test is executed.
861	 */
862	protected void setUp() {
863
864		ht10 = new Hashtable(10);
865		ht100 = new Hashtable(100);
866		htfull = new Hashtable(10);
867		keyVector = new Vector(10);
868		elmVector = new Vector(10);
869
870		for (int i = 0; i < 10; i++) {
871			ht10.put("Key " + i, "Val " + i);
872			keyVector.addElement("Key " + i);
873			elmVector.addElement("Val " + i);
874		}
875
876		for (int i = 0; i < 7; i++)
877			htfull.put("FKey " + i, "FVal " + i);
878	}
879
880    static class ReusableKey {
881        private int key = 0;
882
883        public void setKey(int key) {
884            this.key = key;
885        }
886
887        public int hashCode() {
888            return key;
889        }
890
891        public boolean equals(Object o) {
892            if (o == this) {
893                return true;
894            }
895            if (!(o instanceof ReusableKey)) {
896                return false;
897            }
898            return key == ((ReusableKey) o).key;
899        }
900    }
901}
902