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.tests.java.util;
19
20import libcore.java.util.SpliteratorTester;
21import org.apache.harmony.testframework.serialization.SerializationTest;
22import tests.support.Support_MapTest2;
23import tests.support.Support_UnmodifiableCollectionTest;
24import java.lang.reflect.InvocationHandler;
25import java.lang.reflect.Method;
26import java.util.AbstractMap;
27import java.util.ArrayList;
28import java.util.Arrays;
29import java.util.Collection;
30import java.util.Collections;
31import java.util.Comparator;
32import java.util.ConcurrentModificationException;
33import java.util.HashMap;
34import java.util.HashSet;
35import java.util.Iterator;
36import java.util.Map;
37import java.util.Random;
38import java.util.Set;
39import java.util.Spliterator;
40import java.util.TreeMap;
41
42public class HashMapTest extends junit.framework.TestCase {
43    class MockMap extends AbstractMap {
44        public Set entrySet() {
45            return Collections.EMPTY_SET;
46        }
47
48        public int size() {
49            return 0;
50        }
51    }
52
53    private static class MockMapNull extends AbstractMap {
54        public Set entrySet() {
55            return null;
56        }
57
58        public int size() {
59            return 10;
60        }
61    }
62
63    interface MockInterface {
64        public String mockMethod();
65    }
66
67    class MockClass implements MockInterface {
68        public String mockMethod() {
69            return "This is a MockClass";
70        }
71    }
72
73    class MockHandler implements InvocationHandler {
74
75        Object obj;
76
77        public MockHandler(Object o) {
78            obj = o;
79        }
80
81        public Object invoke(Object proxy, Method m, Object[] args)
82                throws Throwable {
83            Object result = null;
84
85            try {
86                result = m.invoke(obj, args);
87            } catch (Exception e) {
88                e.printStackTrace();
89            }
90            return result;
91        }
92    }
93
94
95    HashMap hm;
96
97    final static int hmSize = 1000;
98
99    Object[] objArray;
100
101    Object[] objArray2;
102
103    /**
104     * java.util.HashMap#HashMap()
105     */
106    public void test_Constructor() {
107        // Test for method java.util.HashMap()
108        new Support_MapTest2(new HashMap()).runTest();
109
110        HashMap hm2 = new HashMap();
111        assertEquals("Created incorrect HashMap", 0, hm2.size());
112    }
113
114    /**
115     * java.util.HashMap#HashMap(int)
116     */
117    public void test_ConstructorI() {
118        // Test for method java.util.HashMap(int)
119        HashMap hm2 = new HashMap(5);
120        assertEquals("Created incorrect HashMap", 0, hm2.size());
121        try {
122            new HashMap(-1);
123            fail("IllegalArgumentException expected");
124        } catch (IllegalArgumentException e) {
125            //expected
126        }
127
128        HashMap empty = new HashMap(0);
129        assertNull("Empty hashmap access", empty.get("nothing"));
130        empty.put("something", "here");
131        assertTrue("cannot get element", empty.get("something") == "here");
132    }
133
134    /**
135     * java.util.HashMap#HashMap(int, float)
136     */
137    public void test_ConstructorIF() {
138        // Test for method java.util.HashMap(int, float)
139        HashMap hm2 = new HashMap(5, (float) 0.5);
140        assertEquals("Created incorrect HashMap", 0, hm2.size());
141        try {
142            new HashMap(0, 0);
143            fail("IllegalArgumentException expected");
144        } catch (IllegalArgumentException e) {
145            //expected
146        }
147
148        HashMap empty = new HashMap(0, 0.75f);
149        assertNull("Empty hashtable access", empty.get("nothing"));
150        empty.put("something", "here");
151        assertTrue("cannot get element", empty.get("something") == "here");
152    }
153
154    /**
155     * java.util.HashMap#HashMap(java.util.Map)
156     */
157    public void test_ConstructorLjava_util_Map() {
158        // Test for method java.util.HashMap(java.util.Map)
159        Map myMap = new TreeMap();
160        for (int counter = 0; counter < hmSize; counter++)
161            myMap.put(objArray2[counter], objArray[counter]);
162        HashMap hm2 = new HashMap(myMap);
163        for (int counter = 0; counter < hmSize; counter++)
164            assertTrue("Failed to construct correct HashMap", hm
165                    .get(objArray2[counter]) == hm2.get(objArray2[counter]));
166
167        Map mockMap = new MockMap();
168        hm = new HashMap(mockMap);
169        assertEquals(hm, mockMap);
170    }
171
172    /**
173     * java.util.HashMap#clear()
174     */
175    public void test_clear() {
176        hm.clear();
177        assertEquals("Clear failed to reset size", 0, hm.size());
178        for (int i = 0; i < hmSize; i++)
179            assertNull("Failed to clear all elements",
180                    hm.get(objArray2[i]));
181
182        // Check clear on a large loaded map of Integer keys
183        HashMap<Integer, String> map = new HashMap<Integer, String>();
184        for (int i = -32767; i < 32768; i++) {
185            map.put(i, "foobar");
186        }
187        map.clear();
188        assertEquals("Failed to reset size on large integer map", 0, hm.size());
189        for (int i = -32767; i < 32768; i++) {
190            assertNull("Failed to clear integer map values", map.get(i));
191        }
192    }
193
194    /**
195     * java.util.HashMap#clone()
196     */
197    public void test_clone() {
198        // Test for method java.lang.Object java.util.HashMap.clone()
199        HashMap hm2 = (HashMap) hm.clone();
200        assertTrue("Clone answered equivalent HashMap", hm2 != hm);
201        for (int counter = 0; counter < hmSize; counter++)
202            assertTrue("Clone answered unequal HashMap", hm
203                    .get(objArray2[counter]) == hm2.get(objArray2[counter]));
204
205        HashMap map = new HashMap();
206        map.put("key", "value");
207        // get the keySet() and values() on the original Map
208        Set keys = map.keySet();
209        Collection values = map.values();
210        assertEquals("values() does not work",
211                "value", values.iterator().next());
212        assertEquals("keySet() does not work",
213                "key", keys.iterator().next());
214        AbstractMap map2 = (AbstractMap) map.clone();
215        map2.put("key", "value2");
216        Collection values2 = map2.values();
217        assertTrue("values() is identical", values2 != values);
218        // values() and keySet() on the cloned() map should be different
219        assertEquals("values() was not cloned",
220                "value2", values2.iterator().next());
221        map2.clear();
222        map2.put("key2", "value3");
223        Set key2 = map2.keySet();
224        assertTrue("keySet() is identical", key2 != keys);
225        assertEquals("keySet() was not cloned",
226                "key2", key2.iterator().next());
227
228        // regresion test for HARMONY-4603
229        HashMap hashmap = new HashMap();
230        MockClonable mock = new MockClonable(1);
231        hashmap.put(1, mock);
232        assertEquals(1, ((MockClonable) hashmap.get(1)).i);
233        HashMap hm3 = (HashMap) hashmap.clone();
234        assertEquals(1, ((MockClonable) hm3.get(1)).i);
235        mock.i = 0;
236        assertEquals(0, ((MockClonable) hashmap.get(1)).i);
237        assertEquals(0, ((MockClonable) hm3.get(1)).i);
238    }
239
240    /**
241     * java.util.HashMap#containsKey(java.lang.Object)
242     */
243    public void test_containsKeyLjava_lang_Object() {
244        // Test for method boolean
245        // java.util.HashMap.containsKey(java.lang.Object)
246        assertTrue("Returned false for valid key", hm.containsKey(new Integer(
247                876).toString()));
248        assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD"));
249
250        HashMap m = new HashMap();
251        m.put(null, "test");
252        assertTrue("Failed with null key", m.containsKey(null));
253        assertTrue("Failed with missing key matching null hash", !m
254                .containsKey(new Integer(0)));
255    }
256
257    /**
258     * java.util.HashMap#containsValue(java.lang.Object)
259     */
260    public void test_containsValueLjava_lang_Object() {
261        // Test for method boolean
262        // java.util.HashMap.containsValue(java.lang.Object)
263        assertTrue("Returned false for valid value", hm
264                .containsValue(new Integer(875)));
265        assertTrue("Returned true for invalid valie", !hm
266                .containsValue(new Integer(-9)));
267    }
268
269    /**
270     * java.util.HashMap#entrySet()
271     */
272    public void test_entrySet() {
273        // Test for method java.util.Set java.util.HashMap.entrySet()
274        Set s = hm.entrySet();
275        Iterator i = s.iterator();
276        assertTrue("Returned set of incorrect size", hm.size() == s.size());
277        while (i.hasNext()) {
278            Map.Entry m = (Map.Entry) i.next();
279            assertTrue("Returned incorrect entry set", hm.containsKey(m
280                    .getKey())
281                    && hm.containsValue(m.getValue()));
282        }
283
284        Iterator iter = s.iterator();
285        s.remove(iter.next());
286        assertEquals(1001, s.size());
287    }
288
289    /**
290     * java.util.HashMap#entrySet()
291     */
292    public void test_entrySetEquals() {
293        Set s1 = hm.entrySet();
294        Set s2 = new HashMap(hm).entrySet();
295        assertEquals(s1, s2);
296    }
297
298    /**
299     * java.util.HashMap#entrySet()
300     */
301    public void test_removeFromViews() {
302        hm.put("A", null);
303        hm.put("B", null);
304        assertTrue(hm.keySet().remove("A"));
305
306        Map<String, String> m2 = new HashMap<String, String>();
307        m2.put("B", null);
308        assertTrue(hm.entrySet().remove(m2.entrySet().iterator().next()));
309    }
310
311
312    /**
313     * java.util.HashMap#get(java.lang.Object)
314     */
315    public void test_getLjava_lang_Object() {
316        // Test for method java.lang.Object
317        // java.util.HashMap.get(java.lang.Object)
318        assertNull("Get returned non-null for non existent key",
319                hm.get("T"));
320        hm.put("T", "HELLO");
321        assertEquals("Get returned incorrect value for existing key", "HELLO", hm.get("T")
322        );
323
324        HashMap m = new HashMap();
325        m.put(null, "test");
326        assertEquals("Failed with null key", "test", m.get(null));
327        assertNull("Failed with missing key matching null hash", m
328                .get(new Integer(0)));
329
330        // Regression for HARMONY-206
331        ReusableKey k = new ReusableKey();
332        HashMap map = new HashMap();
333        k.setKey(1);
334        map.put(k, "value1");
335
336        k.setKey(18);
337        assertNull(map.get(k));
338
339        k.setKey(17);
340        assertNull(map.get(k));
341    }
342
343    /**
344     * java.util.HashMap#isEmpty()
345     */
346    public void test_isEmpty() {
347        // Test for method boolean java.util.HashMap.isEmpty()
348        assertTrue("Returned false for new map", new HashMap().isEmpty());
349        assertTrue("Returned true for non-empty", !hm.isEmpty());
350    }
351
352    /**
353     * java.util.HashMap#keySet()
354     */
355    public void test_keySet() {
356        // Test for method java.util.Set java.util.HashMap.keySet()
357        Set s = hm.keySet();
358        assertTrue("Returned set of incorrect size()", s.size() == hm.size());
359        for (int i = 0; i < objArray.length; i++)
360            assertTrue("Returned set does not contain all keys", s
361                    .contains(objArray[i].toString()));
362
363        HashMap m = new HashMap();
364        m.put(null, "test");
365        assertTrue("Failed with null key", m.keySet().contains(null));
366        assertNull("Failed with null key", m.keySet().iterator().next());
367
368        Map map = new HashMap(101);
369        map.put(new Integer(1), "1");
370        map.put(new Integer(102), "102");
371        map.put(new Integer(203), "203");
372        Iterator it = map.keySet().iterator();
373        Integer remove1 = (Integer) it.next();
374        it.hasNext();
375        it.remove();
376        Integer remove2 = (Integer) it.next();
377        it.remove();
378        ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
379                new Integer(1), new Integer(102), new Integer(203) }));
380        list.remove(remove1);
381        list.remove(remove2);
382        assertTrue("Wrong result", it.next().equals(list.get(0)));
383        assertEquals("Wrong size", 1, map.size());
384        assertTrue("Wrong contents", map.keySet().iterator().next().equals(
385                list.get(0)));
386
387        Map map2 = new HashMap(101);
388        map2.put(new Integer(1), "1");
389        map2.put(new Integer(4), "4");
390        Iterator it2 = map2.keySet().iterator();
391        Integer remove3 = (Integer) it2.next();
392        Integer next;
393        if (remove3.intValue() == 1)
394            next = new Integer(4);
395        else
396            next = new Integer(1);
397        it2.hasNext();
398        it2.remove();
399        assertTrue("Wrong result 2", it2.next().equals(next));
400        assertEquals("Wrong size 2", 1, map2.size());
401        assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
402                next));
403    }
404
405    /**
406     * java.util.HashMap#put(java.lang.Object, java.lang.Object)
407     */
408    public void test_putLjava_lang_ObjectLjava_lang_Object() {
409        hm.put("KEY", "VALUE");
410        assertEquals("Failed to install key/value pair", "VALUE", hm.get("KEY"));
411
412        HashMap<Object, Object> m = new HashMap<Object, Object>();
413        m.put(new Short((short) 0), "short");
414        m.put(null, "test");
415        m.put(new Integer(0), "int");
416        assertEquals("Failed adding to bucket containing null", "short", m
417                .get(new Short((short) 0)));
418        assertEquals("Failed adding to bucket containing null2", "int", m
419                .get(new Integer(0)));
420
421        // Check my actual key instance is returned
422        HashMap<Integer, String> map = new HashMap<Integer, String>();
423        for (int i = -32767; i < 32768; i++) {
424            map.put(i, "foobar");
425        }
426        Integer myKey = new Integer(0);
427        // Put a new value at the old key position
428        map.put(myKey, "myValue");
429        assertTrue(map.containsKey(myKey));
430        assertEquals("myValue", map.get(myKey));
431        boolean found = false;
432        for (Iterator<Integer> itr = map.keySet().iterator(); itr.hasNext(); ) {
433            Integer key = itr.next();
434            if (found = key == myKey) {
435                break;
436            }
437        }
438        assertFalse("Should not find new key instance in hashmap", found);
439
440        // Add a new key instance and check it is returned
441        assertNotNull(map.remove(myKey));
442        map.put(myKey, "myValue");
443        assertTrue(map.containsKey(myKey));
444        assertEquals("myValue", map.get(myKey));
445        for (Iterator<Integer> itr = map.keySet().iterator(); itr.hasNext(); ) {
446            Integer key = itr.next();
447            if (found = key == myKey) {
448                break;
449            }
450        }
451        assertTrue("Did not find new key instance in hashmap", found);
452
453        // Ensure keys with identical hashcode are stored separately
454        HashMap<Object, Object> objmap = new HashMap<Object, Object>();
455        for (int i = 0; i < 32768; i++) {
456            objmap.put(i, "foobar");
457        }
458        // Put non-equal object with same hashcode
459        MyKey aKey = new MyKey();
460        assertNull(objmap.put(aKey, "value"));
461        assertNull(objmap.remove(new MyKey()));
462        assertEquals("foobar", objmap.get(0));
463        assertEquals("value", objmap.get(aKey));
464    }
465
466    static class MyKey {
467        public MyKey() {
468            super();
469        }
470
471        public int hashCode() {
472            return 0;
473        }
474    }
475
476    /**
477     * java.util.HashMap#putAll(java.util.Map)
478     */
479    public void test_putAllLjava_util_Map() {
480        // Test for method void java.util.HashMap.putAll(java.util.Map)
481        HashMap hm2 = new HashMap();
482        hm2.putAll(hm);
483        for (int i = 0; i < 1000; i++)
484            assertTrue("Failed to clear all elements", hm2.get(
485                    new Integer(i).toString()).equals((new Integer(i))));
486
487        Map mockMap = new MockMap();
488        hm2 = new HashMap();
489        hm2.putAll(mockMap);
490        assertEquals("Size should be 0", 0, hm2.size());
491    }
492
493    /**
494     * java.util.HashMap#putAll(java.util.Map)
495     */
496    public void test_putAllLjava_util_Map_Null() {
497        HashMap hashMap = new HashMap();
498        try {
499            hashMap.putAll(new MockMapNull());
500            fail("Should throw NullPointerException");
501        } catch (NullPointerException e) {
502            // expected.
503        }
504
505        try {
506            hashMap = new HashMap(new MockMapNull());
507            fail("Should throw NullPointerException");
508        } catch (NullPointerException e) {
509            // expected.
510        }
511    }
512
513    public void test_putAllLjava_util_Map_Resize() {
514        Random rnd = new Random(666);
515
516        Map<Integer,Integer> m1 = new HashMap<Integer, Integer>();
517        int MID = 10000;
518        for (int i = 0; i < MID; i++) {
519            Integer j = rnd.nextInt();
520            m1.put(j, j);
521        }
522
523        Map<Integer,Integer> m2 = new HashMap<Integer, Integer>();
524        int HI = 30000;
525        for (int i = MID; i < HI; i++) {
526            Integer j = rnd.nextInt();
527            m2.put(j, j);
528        }
529
530        m1.putAll(m2);
531
532        rnd = new Random(666);
533        for (int i = 0; i < HI; i++) {
534            Integer j = rnd.nextInt();
535            assertEquals(j, m1.get(j));
536        }
537    }
538
539    /**
540     * java.util.HashMap#remove(java.lang.Object)
541     */
542    public void test_removeLjava_lang_Object() {
543        int size = hm.size();
544        Integer y = new Integer(9);
545        Integer x = ((Integer) hm.remove(y.toString()));
546        assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
547        assertNull("Failed to remove given key", hm.get(new Integer(9)));
548        assertTrue("Failed to decrement size", hm.size() == (size - 1));
549        assertNull("Remove of non-existent key returned non-null", hm
550                .remove("LCLCLC"));
551
552        HashMap m = new HashMap();
553        m.put(null, "test");
554        assertNull("Failed with same hash as null",
555                m.remove(new Integer(0)));
556        assertEquals("Failed with null key", "test", m.remove(null));
557
558        HashMap<Integer, Object> map = new HashMap<Integer, Object>();
559        for (int i = 0; i < 32768; i++) {
560            map.put(i, "const");
561        }
562        Object[] values = new Object[32768];
563        for (int i = 0; i < 32768; i++) {
564            values[i] = new Object();
565            map.put(i, values[i]);
566        }
567        for (int i = 32767; i >= 0; i--) {
568            assertEquals("Failed to remove same value", values[i], map.remove(i));
569        }
570
571        // Ensure keys with identical hashcode are removed properly
572        map = new HashMap<Integer, Object>();
573        for (int i = -32767; i < 32768; i++) {
574            map.put(i, "foobar");
575        }
576        // Remove non equal object with same hashcode
577        assertNull(map.remove(new MyKey()));
578        assertEquals("foobar", map.get(0));
579        map.remove(0);
580        assertNull(map.get(0));
581    }
582
583    /**
584     * java.util.HashMap#size()
585     */
586    public void test_size() {
587        // Test for method int java.util.HashMap.size()
588        assertTrue("Returned incorrect size",
589                hm.size() == (objArray.length + 2));
590    }
591
592    /**
593     * java.util.HashMap#values()
594     */
595    public void test_values() {
596        // Test for method java.util.Collection java.util.HashMap.values()
597        Collection c = hm.values();
598        assertTrue("Returned collection of incorrect size()", c.size() == hm
599                .size());
600        for (int i = 0; i < objArray.length; i++)
601            assertTrue("Returned collection does not contain all keys", c
602                    .contains(objArray[i]));
603
604        HashMap myHashMap = new HashMap();
605        for (int i = 0; i < 100; i++)
606            myHashMap.put(objArray2[i], objArray[i]);
607        Collection values = myHashMap.values();
608        new Support_UnmodifiableCollectionTest(
609                "Test Returned Collection From HashMap.values()", values)
610                .runTest();
611        values.remove(new Integer(0));
612        assertTrue(
613                "Removing from the values collection should remove from the original map",
614                !myHashMap.containsValue(new Integer(0)));
615
616    }
617
618    /**
619     * java.util.AbstractMap#toString()
620     */
621    public void test_toString() {
622
623        HashMap m = new HashMap();
624        m.put(m, m);
625        String result = m.toString();
626        assertTrue("should contain self ref", result.indexOf("(this") > -1);
627    }
628
629    static class ReusableKey {
630        private int key = 0;
631
632        public void setKey(int key) {
633            this.key = key;
634        }
635
636        public int hashCode() {
637            return key;
638        }
639
640        public boolean equals(Object o) {
641            if (o == this) {
642                return true;
643            }
644            if (!(o instanceof ReusableKey)) {
645                return false;
646            }
647            return key == ((ReusableKey) o).key;
648        }
649    }
650
651    public void test_Map_Entry_hashCode() {
652        //Related to HARMONY-403
653        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(10);
654        Integer key = new Integer(1);
655        Integer val = new Integer(2);
656        map.put(key, val);
657        int expected = key.hashCode() ^ val.hashCode();
658        assertEquals(expected, map.hashCode());
659        key = new Integer(4);
660        val = new Integer(8);
661        map.put(key, val);
662        expected += key.hashCode() ^ val.hashCode();
663        assertEquals(expected, map.hashCode());
664    }
665
666    class MockClonable implements Cloneable {
667        public int i;
668
669        public MockClonable(int i) {
670            this.i = i;
671        }
672
673        @Override
674        protected Object clone() throws CloneNotSupportedException {
675            return new MockClonable(i);
676        }
677    }
678
679    /*
680    * Regression test for HY-4750
681    */
682    public void test_EntrySet() {
683        HashMap map = new HashMap();
684        map.put(new Integer(1), "ONE");
685
686        Set entrySet = map.entrySet();
687        Iterator e = entrySet.iterator();
688        Object real = e.next();
689        Map.Entry copyEntry = new MockEntry();
690        assertEquals(real, copyEntry);
691        assertTrue(entrySet.contains(copyEntry));
692
693        entrySet.remove(copyEntry);
694        assertFalse(entrySet.contains(copyEntry));
695    }
696
697    public void test_forEach() throws Exception {
698        HashMap<String, String> map = new HashMap<>();
699        map.put("one", "1");
700        map.put("two", "2");
701        map.put("three", "3");
702
703        HashMap<String, String> output = new HashMap<>();
704        map.forEach((k, v) -> output.put(k,v));
705        assertEquals(map, output);
706
707        HashSet<String> setOutput = new HashSet<>();
708        map.keySet().forEach((k) -> setOutput.add(k));
709        assertEquals(map.keySet(), setOutput);
710
711        setOutput.clear();
712        map.values().forEach((v) -> setOutput.add(v));
713        assertEquals(new HashSet<>(map.values()), setOutput);
714
715        HashSet<Map.Entry<String,String>> entrySetOutput = new HashSet<>();
716        map.entrySet().forEach((v) -> entrySetOutput.add(v));
717        assertEquals(map.entrySet(), entrySetOutput);
718    }
719
720    public void test_forEach_NPE() throws Exception {
721        HashMap<String, String> map = new HashMap<>();
722        try {
723            map.forEach(null);
724            fail();
725        } catch(NullPointerException expected) {}
726
727        try {
728            map.keySet().forEach(null);
729            fail();
730        } catch(NullPointerException expected) {}
731
732        try {
733            map.values().forEach(null);
734            fail();
735        } catch(NullPointerException expected) {}
736
737        try {
738            map.entrySet().forEach(null);
739            fail();
740        } catch(NullPointerException expected) {}
741    }
742
743    public void test_forEach_CME() throws Exception {
744        HashMap<String, String> map = new HashMap<>();
745        map.put("one", "1");
746        map.put("two", "2");
747        map.put("three", "3");
748
749        HashMap<String, String> outputMap = new HashMap<>();
750        try {
751            map.forEach(new java.util.function.BiConsumer<String, String>() {
752                    @Override
753                    public void accept(String k, String v) {
754                        outputMap.put(k, v);
755                        map.put("foo1", v);
756                    }
757                });
758            fail();
759        } catch(ConcurrentModificationException expected) {}
760        // We should get a CME and DO NOT continue forEach evaluation
761        assertEquals(1, outputMap.size());
762
763        outputMap.clear();
764        try {
765            map.keySet().forEach(new java.util.function.Consumer<String>() {
766                    @Override
767                    public void accept(String k) {
768                        outputMap.put(k, "foo");
769                        map.put("foo2", "boo");
770                    }
771                });
772            fail();
773        } catch(ConcurrentModificationException expected) {}
774        // We should get a CME and DO NOT continue forEach evaluation
775        assertEquals(1, outputMap.size());
776
777        outputMap.clear();
778        try {
779            map.values().forEach(new java.util.function.Consumer<String>() {
780                    @Override
781                    public void accept(String k)  {
782                        outputMap.put(k, "foo");
783                        map.put("foo3", "boo");
784                    }
785                });
786            fail();
787        } catch(ConcurrentModificationException expected) {}
788        // We should get a CME and DO NOT continue forEach evaluation
789        assertEquals(1, outputMap.size());
790
791        outputMap.clear();
792        try {
793            map.entrySet().forEach(new java.util.function.Consumer<Map.Entry<String,String>>() {
794                    @Override
795                    public void accept(Map.Entry<String,String> k)  {
796                        outputMap.put(k.getKey(), "foo");
797                        map.put("foo4", "boo");
798                    }
799                });
800            fail();
801        } catch(ConcurrentModificationException expected) {}
802        // We should get a CME and DO NOT continue forEach evaluation
803        assertEquals(1, outputMap.size());
804    }
805
806    private static class MockEntry implements Map.Entry {
807
808        public Object getKey() {
809            return new Integer(1);
810        }
811
812        public Object getValue() {
813            return "ONE";
814        }
815
816        public Object setValue(Object object) {
817            return null;
818        }
819    }
820
821    public void test_spliterator_keySet() {
822        HashMap<String, String> hashMap = new HashMap<>();
823        hashMap.put("a", "1");
824        hashMap.put("b", "2");
825        hashMap.put("c", "3");
826        hashMap.put("d", "4");
827        hashMap.put("e", "5");
828        hashMap.put("f", "6");
829        hashMap.put("g", "7");
830        hashMap.put("h", "8");
831        hashMap.put("i", "9");
832        hashMap.put("j", "10");
833        hashMap.put("k", "11");
834        hashMap.put("l", "12");
835        hashMap.put("m", "13");
836        hashMap.put("n", "14");
837        hashMap.put("o", "15");
838        hashMap.put("p", "16");
839
840        Set<String> keys = hashMap.keySet();
841        ArrayList<String> expectedKeys = new ArrayList<>(keys);
842
843        SpliteratorTester.runBasicIterationTests(keys.spliterator(), expectedKeys);
844        SpliteratorTester.runBasicSplitTests(keys, expectedKeys);
845        SpliteratorTester.testSpliteratorNPE(keys.spliterator());
846
847        assertTrue(keys.spliterator().hasCharacteristics(Spliterator.SIZED | Spliterator.DISTINCT));
848
849        SpliteratorTester.runSizedTests(keys.spliterator(), 16);
850        SpliteratorTester.runDistinctTests(keys);
851        SpliteratorTester.assertSupportsTrySplit(keys);
852    }
853
854    public void test_spliterator_valueSet() {
855        HashMap<String, String> hashMap = new HashMap<>();
856        hashMap.put("a", "1");
857        hashMap.put("b", "2");
858        hashMap.put("c", "3");
859        hashMap.put("d", "4");
860        hashMap.put("e", "5");
861        hashMap.put("f", "6");
862        hashMap.put("g", "7");
863        hashMap.put("h", "8");
864        hashMap.put("i", "9");
865        hashMap.put("j", "10");
866        hashMap.put("k", "11");
867        hashMap.put("l", "12");
868        hashMap.put("m", "13");
869        hashMap.put("n", "14");
870        hashMap.put("o", "15");
871        hashMap.put("p", "16");
872
873        Collection<String> values = hashMap.values();
874        ArrayList<String> expectedValues = new ArrayList<>(values);
875
876        SpliteratorTester.runBasicIterationTests(values.spliterator(), expectedValues);
877        SpliteratorTester.runBasicSplitTests(values, expectedValues);
878        SpliteratorTester.testSpliteratorNPE(values.spliterator());
879
880        assertTrue(values.spliterator().hasCharacteristics(Spliterator.SIZED));
881
882        SpliteratorTester.runSizedTests(values.spliterator(), 16);
883        SpliteratorTester.assertSupportsTrySplit(values);
884    }
885
886    public void test_spliterator_entrySet() {
887        HashMap<String, String> hashMap = new HashMap<>();
888        hashMap.put("a", "1");
889        hashMap.put("b", "2");
890        hashMap.put("c", "3");
891        hashMap.put("d", "4");
892        hashMap.put("e", "5");
893        hashMap.put("f", "6");
894        hashMap.put("g", "7");
895        hashMap.put("h", "8");
896        hashMap.put("i", "9");
897        hashMap.put("j", "10");
898        hashMap.put("k", "11");
899        hashMap.put("l", "12");
900        hashMap.put("m", "13");
901        hashMap.put("n", "14");
902        hashMap.put("o", "15");
903        hashMap.put("p", "16");
904
905        Set<Map.Entry<String, String>> values = hashMap.entrySet();
906        ArrayList<Map.Entry<String, String>> expectedValues = new ArrayList<>(values);
907
908        Comparator<Map.Entry<String, String>> comparator =
909                (a, b) -> (a.getKey().compareTo(b.getKey()));
910
911        SpliteratorTester.runBasicIterationTests(values.spliterator(), expectedValues);
912        SpliteratorTester.runBasicSplitTests(values, expectedValues, comparator);
913        SpliteratorTester.testSpliteratorNPE(values.spliterator());
914
915        assertTrue(values.spliterator().hasCharacteristics(Spliterator.SIZED | Spliterator.DISTINCT));
916
917        SpliteratorTester.runSizedTests(values.spliterator(), 16);
918        SpliteratorTester.runDistinctTests(values);
919        SpliteratorTester.assertSupportsTrySplit(values);
920    }
921
922    /**
923     * Sets up the fixture, for example, open a network connection. This method
924     * is called before a test is executed.
925     */
926    protected void setUp() {
927        objArray = new Object[hmSize];
928        objArray2 = new Object[hmSize];
929        for (int i = 0; i < objArray.length; i++) {
930            objArray[i] = new Integer(i);
931            objArray2[i] = objArray[i].toString();
932        }
933
934        hm = new HashMap();
935        for (int i = 0; i < objArray.length; i++)
936            hm.put(objArray2[i], objArray[i]);
937        hm.put("test", null);
938        hm.put(null, "test");
939    }
940
941    protected void tearDown() {
942        hm = null;
943        objArray = null;
944        objArray2 = null;
945    }
946
947    class SubMap<K, V> extends HashMap<K, V> {
948        public SubMap(Map<? extends K, ? extends V> m) {
949            super(m);
950        }
951
952        public V put(K key, V value) {
953            throw new UnsupportedOperationException();
954        }
955    }
956
957    /**
958     * serialization/deserialization.
959     */
960    public void testSerializationSelf() throws Exception {
961        HashMap<String, String> hm = new HashMap<String, String>();
962        hm.put("key", "value");
963
964        SerializationTest.verifySelf(hm);
965
966        //  regression for HARMONY-1583
967        hm.put(null, "null");
968        SerializationTest.verifySelf(hm);
969    }
970}
971
972