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