001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.luni.tests.java.util;
019:
020: import java.util.AbstractMap;
021: import java.util.ArrayList;
022: import java.util.Arrays;
023: import java.util.Collection;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.Map;
027: import java.util.Set;
028: import java.util.TreeMap;
029: import java.util.Map.Entry;
030:
031: import org.apache.harmony.testframework.serialization.SerializationTest;
032:
033: import tests.support.Support_MapTest2;
034: import tests.support.Support_UnmodifiableCollectionTest;
035:
036: public class HashMapTest extends junit.framework.TestCase {
037: class MockMap extends AbstractMap {
038: public Set entrySet() {
039: return null;
040: }
041:
042: public int size() {
043: return 0;
044: }
045: }
046:
047: private static class MockMapNull extends AbstractMap {
048: public Set entrySet() {
049: return null;
050: }
051:
052: public int size() {
053: return 10;
054: }
055: }
056:
057: HashMap hm;
058:
059: final static int hmSize = 1000;
060:
061: static Object[] objArray;
062:
063: static Object[] objArray2;
064: {
065: objArray = new Object[hmSize];
066: objArray2 = new Object[hmSize];
067: for (int i = 0; i < objArray.length; i++) {
068: objArray[i] = new Integer(i);
069: objArray2[i] = objArray[i].toString();
070: }
071: }
072:
073: /**
074: * @tests java.util.HashMap#HashMap()
075: */
076: public void test_Constructor() {
077: // Test for method java.util.HashMap()
078: new Support_MapTest2(new HashMap()).runTest();
079:
080: HashMap hm2 = new HashMap();
081: assertEquals("Created incorrect HashMap", 0, hm2.size());
082: }
083:
084: /**
085: * @tests java.util.HashMap#HashMap(int)
086: */
087: public void test_ConstructorI() {
088: // Test for method java.util.HashMap(int)
089: HashMap hm2 = new HashMap(5);
090: assertEquals("Created incorrect HashMap", 0, hm2.size());
091: try {
092: new HashMap(-1);
093: } catch (IllegalArgumentException e) {
094: return;
095: }
096: fail("Failed to throw IllegalArgumentException for initial capacity < 0");
097:
098: HashMap empty = new HashMap(0);
099: assertNull("Empty hashmap access", empty.get("nothing"));
100: empty.put("something", "here");
101: assertTrue("cannot get element",
102: empty.get("something") == "here");
103: }
104:
105: /**
106: * @tests java.util.HashMap#HashMap(int, float)
107: */
108: public void test_ConstructorIF() {
109: // Test for method java.util.HashMap(int, float)
110: HashMap hm2 = new HashMap(5, (float) 0.5);
111: assertEquals("Created incorrect HashMap", 0, hm2.size());
112: try {
113: new HashMap(0, 0);
114: } catch (IllegalArgumentException e) {
115: return;
116: }
117: fail("Failed to throw IllegalArgumentException for initial load factor <= 0");
118:
119: HashMap empty = new HashMap(0, 0.75f);
120: assertNull("Empty hashtable access", empty.get("nothing"));
121: empty.put("something", "here");
122: assertTrue("cannot get element",
123: empty.get("something") == "here");
124: }
125:
126: /**
127: * @tests java.util.HashMap#HashMap(java.util.Map)
128: */
129: public void test_ConstructorLjava_util_Map() {
130: // Test for method java.util.HashMap(java.util.Map)
131: Map myMap = new TreeMap();
132: for (int counter = 0; counter < hmSize; counter++)
133: myMap.put(objArray2[counter], objArray[counter]);
134: HashMap hm2 = new HashMap(myMap);
135: for (int counter = 0; counter < hmSize; counter++)
136: assertTrue("Failed to construct correct HashMap", hm
137: .get(objArray2[counter]) == hm2
138: .get(objArray2[counter]));
139:
140: try {
141: Map mockMap = new MockMap();
142: hm = new HashMap(mockMap);
143: fail("Should throw NullPointerException");
144: } catch (NullPointerException e) {
145: //empty
146: }
147:
148: HashMap map = new HashMap();
149: map.put("a", "a");
150: SubMap map2 = new SubMap(map);
151: assertTrue(map2.containsKey("a"));
152: assertTrue(map2.containsValue("a"));
153: }
154:
155: /**
156: * @tests java.util.HashMap#clear()
157: */
158: public void test_clear() {
159: hm.clear();
160: assertEquals("Clear failed to reset size", 0, hm.size());
161: for (int i = 0; i < hmSize; i++)
162: assertNull("Failed to clear all elements", hm
163: .get(objArray2[i]));
164:
165: // Check clear on a large loaded map of Integer keys
166: HashMap<Integer, String> map = new HashMap<Integer, String>();
167: for (int i = -32767; i < 32768; i++) {
168: map.put(i, "foobar");
169: }
170: map.clear();
171: assertEquals("Failed to reset size on large integer map", 0, hm
172: .size());
173: for (int i = -32767; i < 32768; i++) {
174: assertNull("Failed to clear integer map values", map.get(i));
175: }
176: }
177:
178: /**
179: * @tests java.util.HashMap#clone()
180: */
181: public void test_clone() {
182: // Test for method java.lang.Object java.util.HashMap.clone()
183: HashMap hm2 = (HashMap) hm.clone();
184: assertTrue("Clone answered equivalent HashMap", hm2 != hm);
185: for (int counter = 0; counter < hmSize; counter++)
186: assertTrue("Clone answered unequal HashMap", hm
187: .get(objArray2[counter]) == hm2
188: .get(objArray2[counter]));
189:
190: HashMap map = new HashMap();
191: map.put("key", "value");
192: // get the keySet() and values() on the original Map
193: Set keys = map.keySet();
194: Collection values = map.values();
195: assertEquals("values() does not work", "value", values
196: .iterator().next());
197: assertEquals("keySet() does not work", "key", keys.iterator()
198: .next());
199: AbstractMap map2 = (AbstractMap) map.clone();
200: map2.put("key", "value2");
201: Collection values2 = map2.values();
202: assertTrue("values() is identical", values2 != values);
203: // values() and keySet() on the cloned() map should be different
204: assertEquals("values() was not cloned", "value2", values2
205: .iterator().next());
206: map2.clear();
207: map2.put("key2", "value3");
208: Set key2 = map2.keySet();
209: assertTrue("keySet() is identical", key2 != keys);
210: assertEquals("keySet() was not cloned", "key2", key2.iterator()
211: .next());
212:
213: // regresion test for HARMONY-4603
214: HashMap hashmap = new HashMap();
215: MockClonable mock = new MockClonable(1);
216: hashmap.put(1, mock);
217: assertEquals(1, ((MockClonable) hashmap.get(1)).i);
218: HashMap hm3 = (HashMap) hashmap.clone();
219: assertEquals(1, ((MockClonable) hm3.get(1)).i);
220: mock.i = 0;
221: assertEquals(0, ((MockClonable) hashmap.get(1)).i);
222: assertEquals(0, ((MockClonable) hm3.get(1)).i);
223: }
224:
225: /**
226: * @tests java.util.HashMap#containsKey(java.lang.Object)
227: */
228: public void test_containsKeyLjava_lang_Object() {
229: // Test for method boolean
230: // java.util.HashMap.containsKey(java.lang.Object)
231: assertTrue("Returned false for valid key", hm
232: .containsKey(new Integer(876).toString()));
233: assertTrue("Returned true for invalid key", !hm
234: .containsKey("KKDKDKD"));
235:
236: HashMap m = new HashMap();
237: m.put(null, "test");
238: assertTrue("Failed with null key", m.containsKey(null));
239: assertTrue("Failed with missing key matching null hash", !m
240: .containsKey(new Integer(0)));
241: }
242:
243: /**
244: * @tests java.util.HashMap#containsValue(java.lang.Object)
245: */
246: public void test_containsValueLjava_lang_Object() {
247: // Test for method boolean
248: // java.util.HashMap.containsValue(java.lang.Object)
249: assertTrue("Returned false for valid value", hm
250: .containsValue(new Integer(875)));
251: assertTrue("Returned true for invalid valie", !hm
252: .containsValue(new Integer(-9)));
253: }
254:
255: /**
256: * @tests java.util.HashMap#entrySet()
257: */
258: public void test_entrySet() {
259: // Test for method java.util.Set java.util.HashMap.entrySet()
260: Set s = hm.entrySet();
261: Iterator i = s.iterator();
262: assertTrue("Returned set of incorrect size", hm.size() == s
263: .size());
264: while (i.hasNext()) {
265: Map.Entry m = (Map.Entry) i.next();
266: assertTrue("Returned incorrect entry set", hm.containsKey(m
267: .getKey())
268: && hm.containsValue(m.getValue()));
269: }
270:
271: Iterator iter = s.iterator();
272: s.remove(iter.next());
273: assertEquals(1001, s.size());
274: }
275:
276: /**
277: * @tests java.util.HashMap#get(java.lang.Object)
278: */
279: public void test_getLjava_lang_Object() {
280: // Test for method java.lang.Object
281: // java.util.HashMap.get(java.lang.Object)
282: assertNull("Get returned non-null for non existent key", hm
283: .get("T"));
284: hm.put("T", "HELLO");
285: assertEquals("Get returned incorrect value for existing key",
286: "HELLO", hm.get("T"));
287:
288: HashMap m = new HashMap();
289: m.put(null, "test");
290: assertEquals("Failed with null key", "test", m.get(null));
291: assertNull("Failed with missing key matching null hash", m
292: .get(new Integer(0)));
293:
294: // Regression for HARMONY-206
295: ReusableKey k = new ReusableKey();
296: HashMap map = new HashMap();
297: k.setKey(1);
298: map.put(k, "value1");
299:
300: k.setKey(18);
301: assertNull(map.get(k));
302:
303: k.setKey(17);
304: assertNull(map.get(k));
305: }
306:
307: /**
308: * @tests java.util.HashMap#isEmpty()
309: */
310: public void test_isEmpty() {
311: // Test for method boolean java.util.HashMap.isEmpty()
312: assertTrue("Returned false for new map", new HashMap()
313: .isEmpty());
314: assertTrue("Returned true for non-empty", !hm.isEmpty());
315: }
316:
317: /**
318: * @tests java.util.HashMap#keySet()
319: */
320: public void test_keySet() {
321: // Test for method java.util.Set java.util.HashMap.keySet()
322: Set s = hm.keySet();
323: assertTrue("Returned set of incorrect size()", s.size() == hm
324: .size());
325: for (int i = 0; i < objArray.length; i++)
326: assertTrue("Returned set does not contain all keys", s
327: .contains(objArray[i].toString()));
328:
329: HashMap m = new HashMap();
330: m.put(null, "test");
331: assertTrue("Failed with null key", m.keySet().contains(null));
332: assertNull("Failed with null key", m.keySet().iterator().next());
333:
334: Map map = new HashMap(101);
335: map.put(new Integer(1), "1");
336: map.put(new Integer(102), "102");
337: map.put(new Integer(203), "203");
338: Iterator it = map.keySet().iterator();
339: Integer remove1 = (Integer) it.next();
340: it.hasNext();
341: it.remove();
342: Integer remove2 = (Integer) it.next();
343: it.remove();
344: ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
345: new Integer(1), new Integer(102), new Integer(203) }));
346: list.remove(remove1);
347: list.remove(remove2);
348: assertTrue("Wrong result", it.next().equals(list.get(0)));
349: assertEquals("Wrong size", 1, map.size());
350: assertTrue("Wrong contents", map.keySet().iterator().next()
351: .equals(list.get(0)));
352:
353: Map map2 = new HashMap(101);
354: map2.put(new Integer(1), "1");
355: map2.put(new Integer(4), "4");
356: Iterator it2 = map2.keySet().iterator();
357: Integer remove3 = (Integer) it2.next();
358: Integer next;
359: if (remove3.intValue() == 1)
360: next = new Integer(4);
361: else
362: next = new Integer(1);
363: it2.hasNext();
364: it2.remove();
365: assertTrue("Wrong result 2", it2.next().equals(next));
366: assertEquals("Wrong size 2", 1, map2.size());
367: assertTrue("Wrong contents 2", map2.keySet().iterator().next()
368: .equals(next));
369: }
370:
371: /**
372: * @tests java.util.HashMap#put(java.lang.Object, java.lang.Object)
373: */
374: public void test_putLjava_lang_ObjectLjava_lang_Object() {
375: hm.put("KEY", "VALUE");
376: assertEquals("Failed to install key/value pair", "VALUE", hm
377: .get("KEY"));
378:
379: HashMap<Object, Object> m = new HashMap<Object, Object>();
380: m.put(new Short((short) 0), "short");
381: m.put(null, "test");
382: m.put(new Integer(0), "int");
383: assertEquals("Failed adding to bucket containing null",
384: "short", m.get(new Short((short) 0)));
385: assertEquals("Failed adding to bucket containing null2", "int",
386: m.get(new Integer(0)));
387:
388: // Check my actual key instance is returned
389: HashMap<Integer, String> map = new HashMap<Integer, String>();
390: for (int i = -32767; i < 32768; i++) {
391: map.put(i, "foobar");
392: }
393: Integer myKey = new Integer(0);
394: // Put a new value at the old key position
395: map.put(myKey, "myValue");
396: assertTrue(map.containsKey(myKey));
397: assertEquals("myValue", map.get(myKey));
398: boolean found = false;
399: for (Iterator<Integer> itr = map.keySet().iterator(); itr
400: .hasNext();) {
401: Integer key = itr.next();
402: if (found = key == myKey) {
403: break;
404: }
405: }
406: assertFalse("Should not find new key instance in hashmap",
407: found);
408:
409: // Add a new key instance and check it is returned
410: assertNotNull(map.remove(myKey));
411: map.put(myKey, "myValue");
412: assertTrue(map.containsKey(myKey));
413: assertEquals("myValue", map.get(myKey));
414: for (Iterator<Integer> itr = map.keySet().iterator(); itr
415: .hasNext();) {
416: Integer key = itr.next();
417: if (found = key == myKey) {
418: break;
419: }
420: }
421: assertTrue("Did not find new key instance in hashmap", found);
422:
423: // Ensure keys with identical hashcode are stored separately
424: HashMap<Object, Object> objmap = new HashMap<Object, Object>();
425: for (int i = 0; i < 32768; i++) {
426: objmap.put(i, "foobar");
427: }
428: // Put non-equal object with same hashcode
429: MyKey aKey = new MyKey();
430: assertNull(objmap.put(aKey, "value"));
431: assertNull(objmap.remove(new MyKey()));
432: assertEquals("foobar", objmap.get(0));
433: assertEquals("value", objmap.get(aKey));
434: }
435:
436: static class MyKey {
437: public MyKey() {
438: super ();
439: }
440:
441: public int hashCode() {
442: return 0;
443: }
444: }
445:
446: /**
447: * @tests java.util.HashMap#putAll(java.util.Map)
448: */
449: public void test_putAllLjava_util_Map() {
450: // Test for method void java.util.HashMap.putAll(java.util.Map)
451: HashMap hm2 = new HashMap();
452: hm2.putAll(hm);
453: for (int i = 0; i < 1000; i++)
454: assertTrue("Failed to clear all elements", hm2.get(
455: new Integer(i).toString()).equals((new Integer(i))));
456:
457: Map mockMap = new MockMap();
458: hm2 = new HashMap();
459: hm2.putAll(mockMap);
460: assertEquals("Size should be 0", 0, hm2.size());
461: }
462:
463: /**
464: * @tests java.util.HashMap#putAll(java.util.Map)
465: */
466: public void test_putAllLjava_util_Map_Null() {
467: HashMap hashMap = new HashMap();
468: try {
469: hashMap.putAll(new MockMapNull());
470: fail("Should throw NullPointerException");
471: } catch (NullPointerException e) {
472: // expected.
473: }
474:
475: try {
476: hashMap = new HashMap(new MockMapNull());
477: fail("Should throw NullPointerException");
478: } catch (NullPointerException e) {
479: // expected.
480: }
481: }
482:
483: /**
484: * @tests java.util.HashMap#remove(java.lang.Object)
485: */
486: public void test_removeLjava_lang_Object() {
487: int size = hm.size();
488: Integer y = new Integer(9);
489: Integer x = ((Integer) hm.remove(y.toString()));
490: assertTrue("Remove returned incorrect value", x
491: .equals(new Integer(9)));
492: assertNull("Failed to remove given key", hm.get(new Integer(9)));
493: assertTrue("Failed to decrement size", hm.size() == (size - 1));
494: assertNull("Remove of non-existent key returned non-null", hm
495: .remove("LCLCLC"));
496:
497: HashMap m = new HashMap();
498: m.put(null, "test");
499: assertNull("Failed with same hash as null", m
500: .remove(new Integer(0)));
501: assertEquals("Failed with null key", "test", m.remove(null));
502:
503: HashMap<Integer, Object> map = new HashMap<Integer, Object>();
504: for (int i = 0; i < 32768; i++) {
505: map.put(i, "const");
506: }
507: Object[] values = new Object[32768];
508: for (int i = 0; i < 32768; i++) {
509: values[i] = new Object();
510: map.put(i, values[i]);
511: }
512: for (int i = 32767; i >= 0; i--) {
513: assertEquals("Failed to remove same value", values[i], map
514: .remove(i));
515: }
516:
517: // Ensure keys with identical hashcode are removed properly
518: map = new HashMap<Integer, Object>();
519: for (int i = -32767; i < 32768; i++) {
520: map.put(i, "foobar");
521: }
522: // Remove non equal object with same hashcode
523: assertNull(map.remove(new MyKey()));
524: assertEquals("foobar", map.get(0));
525: map.remove(0);
526: assertNull(map.get(0));
527: }
528:
529: /**
530: * @tests java.util.HashMap#size()
531: */
532: public void test_size() {
533: // Test for method int java.util.HashMap.size()
534: assertTrue("Returned incorrect size",
535: hm.size() == (objArray.length + 2));
536: }
537:
538: /**
539: * @tests java.util.HashMap#values()
540: */
541: public void test_values() {
542: // Test for method java.util.Collection java.util.HashMap.values()
543: Collection c = hm.values();
544: assertTrue("Returned collection of incorrect size()",
545: c.size() == hm.size());
546: for (int i = 0; i < objArray.length; i++)
547: assertTrue("Returned collection does not contain all keys",
548: c.contains(objArray[i]));
549:
550: HashMap myHashMap = new HashMap();
551: for (int i = 0; i < 100; i++)
552: myHashMap.put(objArray2[i], objArray[i]);
553: Collection values = myHashMap.values();
554: new Support_UnmodifiableCollectionTest(
555: "Test Returned Collection From HashMap.values()",
556: values).runTest();
557: values.remove(new Integer(0));
558: assertTrue(
559: "Removing from the values collection should remove from the original map",
560: !myHashMap.containsValue(new Integer(0)));
561:
562: }
563:
564: static class ReusableKey {
565: private int key = 0;
566:
567: public void setKey(int key) {
568: this .key = key;
569: }
570:
571: public int hashCode() {
572: return key;
573: }
574:
575: public boolean equals(Object o) {
576: if (o == this ) {
577: return true;
578: }
579: if (!(o instanceof ReusableKey)) {
580: return false;
581: }
582: return key == ((ReusableKey) o).key;
583: }
584: }
585:
586: public void test_Map_Entry_hashCode() {
587: //Related to HARMONY-403
588: HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(
589: 10);
590: Integer key = new Integer(1);
591: Integer val = new Integer(2);
592: map.put(key, val);
593: int expected = key.hashCode() ^ val.hashCode();
594: assertEquals(expected, map.hashCode());
595: key = new Integer(4);
596: val = new Integer(8);
597: map.put(key, val);
598: expected += key.hashCode() ^ val.hashCode();
599: assertEquals(expected, map.hashCode());
600: }
601:
602: class MockClonable implements Cloneable {
603: public int i;
604:
605: public MockClonable(int i) {
606: this .i = i;
607: }
608:
609: @Override
610: protected Object clone() throws CloneNotSupportedException {
611: return new MockClonable(i);
612: }
613: }
614:
615: /*
616: * Regression test for HY-4750
617: */
618: public void test_EntrySet() {
619: HashMap map = new HashMap();
620: map.put(new Integer(1), "ONE");
621:
622: Set entrySet = map.entrySet();
623: Iterator e = entrySet.iterator();
624: Object real = e.next();
625: Map.Entry copyEntry = new MockEntry();
626: assertEquals(real, copyEntry);
627: assertTrue(entrySet.contains(copyEntry));
628:
629: entrySet.remove(copyEntry);
630: assertFalse(entrySet.contains(copyEntry));
631:
632: }
633:
634: private static class MockEntry implements Map.Entry {
635:
636: public Object getKey() {
637: return new Integer(1);
638: }
639:
640: public Object getValue() {
641: return "ONE";
642: }
643:
644: public Object setValue(Object object) {
645: return null;
646: }
647: }
648:
649: /**
650: * Sets up the fixture, for example, open a network connection. This method
651: * is called before a test is executed.
652: */
653: protected void setUp() {
654: hm = new HashMap();
655: for (int i = 0; i < objArray.length; i++)
656: hm.put(objArray2[i], objArray[i]);
657: hm.put("test", null);
658: hm.put(null, "test");
659: }
660:
661: class SubMap<K, V> extends HashMap<K, V> {
662: public SubMap(Map<? extends K, ? extends V> m) {
663: super (m);
664: }
665:
666: public V put(K key, V value) {
667: throw new UnsupportedOperationException();
668: }
669: }
670:
671: /**
672: * @tests serialization/deserialization.
673: */
674: public void testSerializationSelf() throws Exception {
675: HashMap<String, String> hm = new HashMap<String, String>();
676: hm.put("key", "value");
677:
678: SerializationTest.verifySelf(hm);
679:
680: // regression for HARMONY-1583
681: hm.put(null, "null");
682: SerializationTest.verifySelf(hm);
683: }
684:
685: /**
686: * @tests serialization/deserialization compatibility with RI.
687: */
688: public void testSerializationCompatibility() throws Exception {
689: HashMap<String, String> hm = new HashMap<String, String>();
690: hm.put("key", "value");
691:
692: SerializationTest.verifyGolden(this, hm);
693: }
694:
695: }
|