LinkedHashMapTest.java revision 0976dc2e109a3ca2bd977d18eee74e4b7c9ada30
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package libcore.java.util;
18
19import java.util.ConcurrentModificationException;
20import java.util.LinkedHashMap;
21import java.util.Map;
22import java.util.concurrent.atomic.AtomicBoolean;
23import java.util.concurrent.atomic.AtomicInteger;
24
25public class LinkedHashMapTest extends junit.framework.TestCase {
26
27    public void test_getOrDefault() {
28        MapDefaultMethodTester
29                .test_getOrDefault(new LinkedHashMap<>(), true /*acceptsNullKey*/,
30                        true /*acceptsNullValue*/);
31
32        // Test for access order
33        Map<String, String> m = new LinkedHashMap<String, String>(8, .75f, true);
34        m.put("key", "value");
35        m.put("key1", "value1");
36        m.put("key2", "value2");
37        m.getOrDefault("key1", "value");
38        Map.Entry<String, String> newest = null;
39        for (Map.Entry<String, String> e : m.entrySet()) {
40            newest = e;
41        }
42        assertEquals("key1", newest.getKey());
43        assertEquals("value1", newest.getValue());
44    }
45
46    public void test_forEach() {
47        MapDefaultMethodTester.test_forEach(new LinkedHashMap<>());
48    }
49
50    public void test_putIfAbsent() {
51        MapDefaultMethodTester.test_putIfAbsent(new LinkedHashMap<>(), true /*acceptsNullKey*/,
52                true /*acceptsNullValue*/);
53
54        // Test for access order
55        Map<String, String> m = new LinkedHashMap<String, String>(8, .75f, true);
56        m.putIfAbsent("key", "value");
57        m.putIfAbsent("key1", "value1");
58        m.putIfAbsent("key2", "value2");
59        Map.Entry<String, String> newest = null;
60        for (Map.Entry<String, String> e : m.entrySet()) {
61            newest = e;
62        }
63        assertEquals("key2", newest.getKey());
64        assertEquals("value2", newest.getValue());
65
66        // for existed key
67        m.putIfAbsent("key1", "value1");
68        for (Map.Entry<String, String> e : m.entrySet()) {
69            newest = e;
70        }
71        assertEquals("key1", newest.getKey());
72        assertEquals("value1", newest.getValue());
73    }
74
75    public void test_remove() {
76        MapDefaultMethodTester.test_remove(new LinkedHashMap<>(), true /*acceptsNullKey*/,
77                true /*acceptsNullValue*/);
78    }
79
80    public void test_replace$K$V$V() {
81        MapDefaultMethodTester.
82                test_replace$K$V$V(new LinkedHashMap<>(), true /*acceptsNullKey*/,
83                        true /*acceptsNullValue*/);
84
85        // Test for access order
86        Map<String, String> m = new LinkedHashMap<>(8, .75f, true  /*accessOrder*/);
87        m.put("key", "value");
88        m.put("key1", "value1");
89        m.put("key2", "value2");
90        m.replace("key1", "value1", "value2");
91        Map.Entry<String, String> newest = null;
92        for (Map.Entry<String, String> e : m.entrySet()) {
93            newest = e;
94        }
95        assertEquals("key1", newest.getKey());
96        assertEquals("value2", newest.getValue());
97
98        // for wrong pair of key and value, last accessed node should
99        // not change
100        m.replace("key2", "value1", "value3");
101        for (Map.Entry<String, String> e : m.entrySet()) {
102            newest = e;
103        }
104        assertEquals("key1", newest.getKey());
105        assertEquals("value2", newest.getValue());
106    }
107
108    public void test_replace$K$V() {
109        MapDefaultMethodTester.test_replace$K$V(new LinkedHashMap<>(), true /*acceptsNullKey*/,
110                true /*acceptsNullValue*/);
111
112        // Test for access order
113        Map<String, String> m = new LinkedHashMap<>(8, .75f, true  /*accessOrder*/);
114        m.put("key", "value");
115        m.put("key1", "value1");
116        m.put("key2", "value2");
117        m.replace("key1", "value2");
118        Map.Entry<String, String> newest = null;
119        for (Map.Entry<String, String> e : m.entrySet()) {
120            newest = e;
121        }
122        assertEquals("key1", newest.getKey());
123        assertEquals("value2", newest.getValue());
124    }
125
126    public void test_computeIfAbsent() {
127        MapDefaultMethodTester.test_computeIfAbsent(new LinkedHashMap<>(), true /*acceptsNullKey*/,
128                true /*acceptsNullValue*/);
129
130        // Test for access order
131        Map<String, String> m = new LinkedHashMap<>(8, .75f, true  /*accessOrder*/);
132        m.put("key", "value");
133        m.put("key1", "value1");
134        m.put("key2", "value2");
135        m.computeIfAbsent("key1", (k) -> "value3");
136        Map.Entry<String, String> newest = null;
137        for (Map.Entry<String, String> e : m.entrySet()) {
138            newest = e;
139        }
140        assertEquals("key1", newest.getKey());
141        assertEquals("value1", newest.getValue());
142
143        // When value is absent
144        m.computeIfAbsent("key4", (k) -> "value3");
145        newest = null;
146        for (Map.Entry<String, String> e : m.entrySet()) {
147            newest = e;
148        }
149        assertEquals("key4", newest.getKey());
150        assertEquals("value3", newest.getValue());
151    }
152
153    public void test_computeIfPresent() {
154        MapDefaultMethodTester.test_computeIfPresent(new LinkedHashMap<>(), true /*acceptsNullKey*/);
155
156        // Test for access order
157        Map<String, String> m = new LinkedHashMap<>(8, .75f, true  /*accessOrder*/);
158        m.put("key", "value");
159        m.put("key1", "value1");
160        m.put("key2", "value2");
161        m.computeIfPresent("key1", (k, v) -> "value3");
162        Map.Entry<String, String> newest = null;
163        for (Map.Entry<String, String> e : m.entrySet()) {
164            newest = e;
165        }
166        assertEquals("key1", newest.getKey());
167        assertEquals("value3", newest.getValue());
168    }
169
170    public void test_compute() {
171        MapDefaultMethodTester.test_compute(new LinkedHashMap<>(), true /*acceptsNullKey*/);
172
173        // Test for access order
174        Map<String, String> m = new LinkedHashMap<>(8, .75f, true  /*accessOrder*/);
175        m.put("key", "value");
176        m.put("key1", "value1");
177        m.put("key2", "value2");
178        m.compute("key1", (k, v) -> "value3");
179        Map.Entry<String, String> newest = null;
180        for (Map.Entry<String, String> e : m.entrySet()) {
181            newest = e;
182        }
183        assertEquals("key1", newest.getKey());
184        assertEquals("value3", newest.getValue());
185
186        m.compute("key4", (k, v) -> "value4");
187        newest = null;
188        for (Map.Entry<String, String> e : m.entrySet()) {
189            newest = e;
190        }
191        assertEquals("key4", newest.getKey());
192        assertEquals("value4", newest.getValue());
193    }
194
195    public void test_merge() {
196        MapDefaultMethodTester.test_merge(new LinkedHashMap<>(), true /*acceptsNullKey*/);
197
198        // Test for access order
199        Map<String, String> m = new LinkedHashMap<>(8, .75f, true  /*accessOrder*/);
200        m.put("key", "value");
201        m.put("key1", "value1");
202        m.put("key2", "value2");
203        m.merge("key1", "value3", (k, v) -> "value3");
204        Map.Entry<String, String> newest = null;
205        for (Map.Entry<String, String> e : m.entrySet()) {
206            newest = e;
207        }
208        assertEquals("key1", newest.getKey());
209        assertEquals("value3", newest.getValue());
210    }
211
212    // http://b/27929722
213    // This tests the behaviour is consistent with earlier Android releases.
214    // This behaviour is NOT consistent with the RI. Future Android releases
215    // might change this.
216    public void test_removeEldestEntry() {
217        final AtomicBoolean removeEldestEntryReturnValue = new AtomicBoolean(false);
218        final AtomicInteger removeEldestEntryCallCount = new AtomicInteger(0);
219        LinkedHashMap<String, String> m = new LinkedHashMap<String, String>() {
220            @Override
221            protected boolean removeEldestEntry(Entry eldest) {
222                removeEldestEntryCallCount.incrementAndGet();
223                return removeEldestEntryReturnValue.get();
224            }
225        };
226
227        m.put("foo", "bar");
228        assertEquals(0, removeEldestEntryCallCount.get());
229        m.put("baz", "quux");
230        assertEquals(1, removeEldestEntryCallCount.get());
231
232        removeEldestEntryReturnValue.set(true);
233        m.put("foob", "faab");
234        assertEquals(2, removeEldestEntryCallCount.get());
235        assertEquals(2, m.size());
236        assertFalse(m.containsKey("foo"));
237    }
238
239    public void test_replaceAll() {
240        LinkedHashMap<String, String> map = new LinkedHashMap<>();
241        map.put("one", "1");
242        map.put("two", "2");
243        map.put("three", "3");
244
245        map.replaceAll((k, v) -> k + v);
246        assertEquals("one1", map.get("one"));
247        assertEquals("two2", map.get("two"));
248        assertEquals("three3", map.get("three"));
249        assertEquals(3, map.size());
250
251        try {
252            map.replaceAll(new java.util.function.BiFunction<String, String, String>() {
253                @Override
254                public String apply(String k, String v) {
255                    map.put("foo1", v);
256                    return v;
257                }
258            });
259            fail();
260        } catch(ConcurrentModificationException expected) {}
261
262        try {
263            map.replaceAll(null);
264            fail();
265        } catch(NullPointerException expected) {}
266    }
267}
268