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