1 /* 2 * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4904067 5023830 7129185 8072015 8292955 27 * @summary Unit test for Collections.checkedMap 28 * @author Josh Bloch 29 * @key randomness 30 * @library /test/lib 31 * @run testng CheckedMapBash 32 */ 33 34 import jdk.test.lib.valueclass.VClass; 35 import org.testng.Assert; 36 import org.testng.annotations.DataProvider; 37 import org.testng.annotations.Test; 38 39 import java.util.ArrayList; 40 import java.util.Arrays; 41 import java.util.Collection; 42 import java.util.Collections; 43 import java.util.HashMap; 44 import java.util.Iterator; 45 import java.util.Map; 46 import java.util.Random; 47 import java.util.Set; 48 import java.util.TreeMap; 49 import java.util.function.Supplier; 50 51 import static org.testng.Assert.fail; 52 53 public class CheckedMapBash { 54 static final Random rnd = new Random(); 55 static final Object nil = new Integer(0); 56 static final int numItr = 100; 57 static final int mapSize = 100; 58 59 @Test(dataProvider = "Bash.Supplier<Map<Integer,Integer>>") 60 public static void testCheckedMap(String description, Supplier<Map<Integer,Integer>> supplier) { 61 Map m = supplier.get(); 62 Object head = nil; 63 64 for (int j=0; j<mapSize; j++) { 65 Object newHead; 66 do { 67 newHead = new Integer(rnd.nextInt()); 68 } while (m.containsKey(newHead) || newHead.equals(nil)); 69 m.put(newHead, head); 70 head = newHead; 71 } 72 if (m.size() != mapSize) 73 fail("Size not as expected."); 74 75 { 76 HashMap hm = new HashMap(m); 77 if (! (hm.hashCode() == m.hashCode() && 78 hm.entrySet().hashCode() == m.entrySet().hashCode() && 79 hm.keySet().hashCode() == m.keySet().hashCode())) 80 fail("Incorrect hashCode computation."); 81 82 if (! (hm.equals(m) && 83 hm.entrySet().equals(m.entrySet()) && 84 hm.keySet().equals(m.keySet()) && 85 m.equals(hm) && 86 m.entrySet().equals(hm.entrySet()) && 87 m.keySet().equals(hm.keySet()))) 88 fail("Incorrect equals computation."); 89 } 90 91 Map m2 = supplier.get(); m2.putAll(m); 92 m2.values().removeAll(m.keySet()); 93 if (m2.size()!= 1 || !m2.containsValue(nil)) 94 fail("Collection views test failed."); 95 96 int j=0; 97 while (head != nil) { 98 if (!m.containsKey(head)) 99 fail("Linked list doesn't contain a link."); 100 Object newHead = m.get(head); 101 if (newHead == null) 102 fail("Could not retrieve a link."); 103 m.remove(head); 104 head = newHead; 105 j++; 106 } 107 if (!m.isEmpty()) 108 fail("Map nonempty after removing all links."); 109 if (j != mapSize) 110 fail("Linked list size not as expected."); 111 } 112 113 @Test(dataProvider = "Supplier<Map<Integer,Integer>>") 114 public static void testCheckedMap2(String description, Supplier<Map<Integer,Integer>> supplier) { 115 Map m = supplier.get(); 116 for (int i=0; i<mapSize; i++) 117 if (m.put(new Integer(i), new Integer(2*i)) != null) 118 fail("put returns a non-null value erroneously."); 119 for (int i=0; i<2*mapSize; i++) 120 if (m.containsValue(new Integer(i)) != (i%2==0)) 121 fail("contains value "+i); 122 if (m.put(nil, nil) == null) 123 fail("put returns a null value erroneously."); 124 Map m2 = supplier.get(); m2.putAll(m); 125 if (!m.equals(m2)) 126 fail("Clone not equal to original. (1)"); 127 if (!m2.equals(m)) 128 fail("Clone not equal to original. (2)"); 129 Set s = m.entrySet(), s2 = m2.entrySet(); 130 if (!s.equals(s2)) 131 fail("Clone not equal to original. (3)"); 132 if (!s2.equals(s)) 133 fail("Clone not equal to original. (4)"); 134 if (!s.containsAll(s2)) 135 fail("Original doesn't contain clone!"); 136 if (!s2.containsAll(s)) 137 fail("Clone doesn't contain original!"); 138 139 s2.removeAll(s); 140 if (!m2.isEmpty()) 141 fail("entrySet().removeAll failed."); 142 143 m2.putAll(m); 144 m2.clear(); 145 if (!m2.isEmpty()) 146 fail("clear failed."); 147 148 Iterator i = m.entrySet().iterator(); 149 while (i.hasNext()) { 150 i.next(); 151 i.remove(); 152 } 153 if (!m.isEmpty()) 154 fail("Iterator.remove() failed"); 155 } 156 157 @DataProvider(name = "Bash.Supplier<Map<Integer,Integer>>", parallel = true) 158 public static Iterator<Object[]> bashNavigableMapProvider() { 159 ArrayList<Object[]> iters = new ArrayList<>(makeCheckedMaps()); 160 iters.ensureCapacity(numItr * iters.size()); 161 for (int each=1; each < numItr; each++) { 162 iters.addAll(makeCheckedMaps()); 163 } 164 return iters.iterator(); 165 } 166 167 @DataProvider(name = "Supplier<Map<Integer,Integer>>", parallel = true) 168 public static Iterator<Object[]> navigableMapProvider() { 169 return makeCheckedMaps().iterator(); 170 } 171 172 public static Collection<Object[]> makeCheckedMaps() { 173 Object[][] params = { 174 {"Collections.checkedMap(HashMap)", 175 (Supplier) () -> Collections.checkedMap(new HashMap(), Integer.class, Integer.class)}, 176 {"Collections.checkedMap(TreeMap(reverseOrder))", 177 (Supplier) () -> Collections.checkedMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)}, 178 {"Collections.checkedMap(TreeMap.descendingMap())", 179 (Supplier) () -> Collections.checkedMap(new TreeMap().descendingMap(), Integer.class, Integer.class)}, 180 {"Collections.checkedNavigableMap(TreeMap)", 181 (Supplier) () -> Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class)}, 182 {"Collections.checkedNavigableMap(TreeMap(reverseOrder))", 183 (Supplier) () -> Collections.checkedNavigableMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)}, 184 {"Collections.checkedNavigableMap(TreeMap.descendingMap())", 185 (Supplier) () -> Collections.checkedNavigableMap(new TreeMap().descendingMap(), Integer.class, Integer.class)}, 186 }; 187 return Arrays.asList(params); 188 } 189 190 @Test(groups = "type_check") 191 public static void testCheckedMapMerge() { 192 Map m = Collections.checkedMap(new HashMap<>(), Integer.class, Integer.class); 193 Assert.assertThrows(ClassCastException.class, () -> m.merge("key", "value", (v1, v2) -> null)); 194 Assert.assertThrows(ClassCastException.class, () -> m.merge("key", 3, (v1, v2) -> v2)); 195 } 196 197 @Test 198 public static void testValueCheckedMap() { 199 Map<VClass,VClass> m = Collections.checkedMap(new HashMap<>(), VClass.class, VClass.class); 200 m.put(new VClass(1, new int[] { 1 }), new VClass(10, new int[] { 10 })); 201 if (!m.containsKey(new VClass(1, new int[] { 1 })) || !m.containsValue(new VClass(10, new int[] { 10 }))) 202 fail("value checkedMap lookup failed"); 203 if (!new HashMap<>(m).equals(m)) 204 fail("value checkedMap equals failed"); 205 try { 206 ((Map) m).put("not a Tuple", new VClass(2, new int[] { 2 })); 207 fail("value checkedMap accepted wrong type"); 208 } catch (ClassCastException expected) { } 209 } 210 } --- EOF ---