1 /* 2 * Copyright (c) 2000, 2019, 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 4327164 8229338 27 * @summary Basic test for new RandomAccess interface 28 * @run testng Basic 29 */ 30 31 import org.testng.annotations.DataProvider; 32 import org.testng.annotations.Test; 33 34 import static org.testng.Assert.assertEquals; 35 36 import java.util.*; 37 import java.util.concurrent.CopyOnWriteArrayList; 38 import java.util.function.Function; 39 import java.util.function.Supplier; 40 41 public class Basic { 42 43 /* 44 * Lists which implement Random Access interface 45 */ 46 @DataProvider(name = "testLists") 47 public Object[][] testData() { 48 var intArray = new Integer[100]; 49 var stack = new Stack<>(); 50 var random = new Random(); 51 for (int i = 0; i < 100; i++) { 52 var r = random.nextInt(100); 53 stack.push(r); 54 intArray[i] = r; 55 } 56 List<Integer> list = Arrays.asList(intArray); 57 return new Object[][]{ 58 {list, true, "Arrays.asList"}, 59 {stack, true, "Stack"}, 60 {new ArrayList<>(list), true, "ArrayList"}, 61 {new LinkedList<>(list), false, "LinkedList"}, 62 {new Vector<>(list), true, "Vector"}, 63 {new CopyOnWriteArrayList<>(list), true, "CopyOnWriteArrayList"} 64 }; 65 } 66 67 @Test(dataProvider = "testLists") 68 public void testRandomAccess(List<Integer> list, boolean expectedRA, String failMsg) { 69 70 var actualRA = list instanceof RandomAccess; 71 assertEquals(actualRA, expectedRA, failMsg); 72 73 List<Integer> unmodList = Collections.unmodifiableList(list); 74 List<Integer> syncList = Collections.synchronizedList(list); 75 assertEquals((unmodList instanceof RandomAccess), actualRA, 76 "Unmodifiable fails to preserve RandomAccess"); 77 assertEquals((syncList instanceof RandomAccess), actualRA, 78 "Synchronized fails to preserve RandomAccess"); 79 80 while (list.size() > 0) { 81 list = list.subList(0, list.size() - 1); 82 assertEquals((list instanceof RandomAccess), actualRA, 83 "SubList fails to preserve RandomAccess: " + list.size()); 84 85 unmodList = unmodList.subList(0, unmodList.size() - 1); 86 assertEquals((unmodList instanceof RandomAccess), actualRA, 87 "SubList(unmodifiable) fails to preserve RandomAccess: " 88 + unmodList.size()); 89 90 syncList = syncList.subList(0, syncList.size() - 1); 91 assertEquals((syncList instanceof RandomAccess), actualRA, 92 "SubList(synchronized) fails to preserve RandomAccess: " 93 + syncList.size()); 94 } 95 } 96 97 @Test(dataProvider = "testLists") 98 public void testListCopy(List<Integer> list, boolean expectedRA, String failMsg) { 99 ArrayList testCollection = new ArrayList<>(Collections.nCopies(100, 0)); 100 // Test that copy works on random & sequential access 101 Collections.copy(list, testCollection); 102 assertEquals(list, testCollection, "Copy failed: " + failMsg); 103 } 104 105 @Test(dataProvider = "testLists") 106 public void testListFill(List<Integer> list, boolean expectedRA, String failMsg) { 107 ArrayList testCollection = new ArrayList<>(Collections.nCopies(100, 0)); 108 // Test that copy works on random & sequential access 109 Collections.fill(list, 0); 110 assertEquals(list, testCollection, "Fill failed: " + failMsg); 111 } 112 113 /* 114 * Test that shuffle and binarySearch work the same on random and sequential access lists. 115 */ 116 @DataProvider(name = "testFactoryLists") 117 public Object[][] testDataFactory() { 118 return new Object[][]{ 119 {"ArrayList -> LinkedList", supplier(ArrayList::new), copyCtor(LinkedList::new)}, 120 {"CopyOnWriteArrayList -> Stack", supplier(CopyOnWriteArrayList::new), 121 copyCtor((list) -> { var s = new Stack();s.addAll(list);return s; })} 122 }; 123 } 124 125 private Supplier<List<Integer>> supplier(Supplier<List<Integer>> supplier) { 126 return supplier; 127 } 128 129 private Function<List<Integer>, List<Integer>> copyCtor(Function<List<Integer>, List<Integer>> ctor) { 130 return ctor; 131 } 132 133 @Test(dataProvider = "testFactoryLists") 134 public void testListShuffle(String description, Supplier<List<Integer>> randomAccessListSupplier, 135 Function<List<Integer>, List<Integer>> otherListFactory) { 136 137 //e.g: ArrayList<Integer> al = new ArrayList<>(); 138 List<Integer> l1 = randomAccessListSupplier.get(); 139 for (int j = 0; j < 100; j++) { 140 l1.add(Integer.valueOf(2 * j)); 141 } 142 // e.g: List<Integer> ll = new LinkedList<>(al); 143 List<Integer> l2 = otherListFactory.apply(l1); 144 for (int i = 0; i < 100; i++) { 145 Collections.shuffle(l1, new Random(666)); 146 Collections.shuffle(l2, new Random(666)); 147 assertEquals(l1, l2, "Shuffle failed: " + description); 148 } 149 } 150 151 @Test(dataProvider = "testFactoryLists") 152 public void testListBinarySearch(String description, Supplier<List<Integer>> randomAccessListSupplier, 153 Function<List<Integer>, List<Integer>> otherListFactory) { 154 155 //e.g: ArrayList<Integer> al = new ArrayList<>(); 156 List<Integer> l1 = randomAccessListSupplier.get(); 157 for (int i = 0; i < 10000; i++) { 158 l1.add(Integer.valueOf(2 * i)); 159 } 160 // e.g: List<Integer> ll = new LinkedList<>(al); 161 List<Integer> l2 = otherListFactory.apply(l1); 162 for (int i = 0; i < 500; i++) { 163 Integer key = Integer.valueOf(new Random(666).nextInt(20000)); 164 assertEquals(Collections.binarySearch(l1, key), Collections 165 .binarySearch(l2, key), "Binary search failed: " + description); 166 } 167 } 168 }