19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
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 |
20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 |
23 |
24 /* |
24 /** |
25 * @test |
25 * @test |
26 * @bug 4327164 |
26 * @bug 4327164 8229338 |
27 * @summary Basic test for new RandomAccess interface |
27 * @summary Basic test for new RandomAccess interface |
|
28 * @run testng Basic |
28 */ |
29 */ |
29 |
30 |
30 import java.util.ArrayList; |
31 import org.testng.annotations.DataProvider; |
31 import java.util.Arrays; |
32 import org.testng.annotations.Test; |
32 import java.util.Collections; |
33 |
33 import java.util.LinkedList; |
34 import static org.testng.Assert.assertEquals; |
34 import java.util.List; |
35 |
35 import java.util.Random; |
36 import java.util.*; |
36 import java.util.RandomAccess; |
37 import java.util.concurrent.CopyOnWriteArrayList; |
37 import java.util.Vector; |
38 import java.util.function.Function; |
|
39 import java.util.function.Supplier; |
38 |
40 |
39 public class Basic { |
41 public class Basic { |
40 public static void main(String[] args) throws Exception { |
|
41 List a0 = Arrays.asList(new String[] { "a", "b", "c" }); |
|
42 List a[] = { a0, new ArrayList(a0), new LinkedList(a0), |
|
43 new Vector(a0) }; |
|
44 |
42 |
45 if (!(a[0] instanceof RandomAccess)) |
43 /* |
46 throw new Exception("Arrays.asList doesn't implement RandomAccess"); |
44 * Lists which implement Random Access interface |
47 if (!(a[1] instanceof RandomAccess)) |
45 */ |
48 throw new Exception("ArrayList doesn't implement RandomAccess"); |
46 @DataProvider(name = "testLists") |
49 if (a[2] instanceof RandomAccess) |
47 public Object[][] testData() { |
50 throw new Exception("LinkedList implements RandomAccess"); |
48 var intArray = new Integer[100]; |
51 if (!(a[3] instanceof RandomAccess)) |
49 var stack = new Stack<>(); |
52 throw new Exception("Vector doesn't implement RandomAccess"); |
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 } |
53 |
66 |
54 for (int i = 0; i < a.length; i++) { |
67 @Test(dataProvider = "testLists") |
55 List t = a[i]; |
68 public void testRandomAccess(List<Integer> list, boolean expectedRA, String failMsg) { |
56 List ut = Collections.unmodifiableList(t); |
|
57 List st = Collections.synchronizedList(t); |
|
58 |
69 |
59 boolean random = t instanceof RandomAccess; |
70 var actualRA = list instanceof RandomAccess; |
60 if ((ut instanceof RandomAccess) != random) |
71 assertEquals(actualRA, expectedRA, failMsg); |
61 throw new Exception( |
|
62 "Unmodifiable fails to preserve RandomAccess: " + i); |
|
63 if ((st instanceof RandomAccess) != random) |
|
64 throw new Exception( |
|
65 "Synchronized fails to preserve RandomAccess: " + i); |
|
66 |
72 |
67 while (t.size() > 0) { |
73 List<Integer> unmodList = Collections.unmodifiableList(list); |
68 t = t.subList(0, t.size() - 1); |
74 List<Integer> syncList = Collections.synchronizedList(list); |
69 if ((t instanceof RandomAccess) != random) |
75 assertEquals((unmodList instanceof RandomAccess), actualRA, |
70 throw new Exception( |
76 "Unmodifiable fails to preserve RandomAccess"); |
71 "SubList fails to preserve RandomAccess: " + i |
77 assertEquals((syncList instanceof RandomAccess), actualRA, |
72 + ", " + t.size()); |
78 "Synchronized fails to preserve RandomAccess"); |
73 |
79 |
74 ut = ut.subList(0, ut.size() - 1); |
80 while (list.size() > 0) { |
75 if ((ut instanceof RandomAccess) != random) |
81 list = list.subList(0, list.size() - 1); |
76 throw new Exception( |
82 assertEquals((list instanceof RandomAccess), actualRA, |
77 "SubList(unmodifiable) fails to preserve RandomAccess: " |
83 "SubList fails to preserve RandomAccess: " + list.size()); |
78 + i + ", " + ut.size()); |
|
79 |
84 |
80 st = st.subList(0, st.size() - 1); |
85 unmodList = unmodList.subList(0, unmodList.size() - 1); |
81 if ((st instanceof RandomAccess) != random) |
86 assertEquals((unmodList instanceof RandomAccess), actualRA, |
82 throw new Exception( |
87 "SubList(unmodifiable) fails to preserve RandomAccess: " |
83 "SubList(synchronized) fails to preserve RandomAccess: " |
88 + unmodList.size()); |
84 + i + ", " + st.size()); |
89 |
85 } |
90 syncList = syncList.subList(0, syncList.size() - 1); |
|
91 assertEquals((syncList instanceof RandomAccess), actualRA, |
|
92 "SubList(synchronized) fails to preserve RandomAccess: " |
|
93 + syncList.size()); |
86 } |
94 } |
|
95 } |
87 |
96 |
88 // Test that shuffle works the same on random and sequential access |
97 @Test(dataProvider = "testLists") |
89 List al = new ArrayList(); |
98 public void testListCopy(List<Integer> list, boolean expectedRA, String failMsg) { |
90 for (int j = 0; j < 100; j++) |
99 ArrayList testCollection = new ArrayList<>(Collections.nCopies(100, 0)); |
91 al.add(Integer.valueOf(2 * j)); |
100 // Test that copy works on random & sequential access |
92 List ll = new LinkedList(al); |
101 Collections.copy(list, testCollection); |
93 Random r1 = new Random(666), r2 = new Random(666); |
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); |
94 for (int i = 0; i < 100; i++) { |
144 for (int i = 0; i < 100; i++) { |
95 Collections.shuffle(al, r1); |
145 Collections.shuffle(l1, new Random(666)); |
96 Collections.shuffle(ll, r2); |
146 Collections.shuffle(l2, new Random(666)); |
97 if (!al.equals(ll)) |
147 assertEquals(l1, l2, "Shuffle failed: " + description); |
98 throw new Exception("Shuffle failed: " + i); |
|
99 } |
148 } |
|
149 } |
100 |
150 |
101 // Test that fill works on random & sequential access |
151 @Test(dataProvider = "testFactoryLists") |
102 List gumbyParade = Collections.nCopies(100, "gumby"); |
152 public void testListBinarySearch(String description, Supplier<List<Integer>> randomAccessListSupplier, |
103 Collections.fill(al, "gumby"); |
153 Function<List<Integer>, List<Integer>> otherListFactory) { |
104 if (!al.equals(gumbyParade)) |
|
105 throw new Exception("ArrayList fill failed"); |
|
106 Collections.fill(ll, "gumby"); |
|
107 if (!ll.equals(gumbyParade)) |
|
108 throw new Exception("LinkedList fill failed"); |
|
109 |
154 |
110 // Test that copy works on random & sequential access |
155 //e.g: ArrayList<Integer> al = new ArrayList<>(); |
111 List pokeyParade = Collections.nCopies(100, "pokey"); |
156 List<Integer> l1 = randomAccessListSupplier.get(); |
112 Collections.copy(al, pokeyParade); |
157 for (int i = 0; i < 10000; i++) { |
113 if (!al.equals(pokeyParade)) |
158 l1.add(Integer.valueOf(2 * i)); |
114 throw new Exception("ArrayList copy failed"); |
159 } |
115 Collections.copy(ll, pokeyParade); |
160 // e.g: List<Integer> ll = new LinkedList<>(al); |
116 if (!ll.equals(pokeyParade)) |
161 List<Integer> l2 = otherListFactory.apply(l1); |
117 throw new Exception("LinkedList copy failed"); |
|
118 |
|
119 // Test that binarySearch works the same on random & sequential access |
|
120 al = new ArrayList(); |
|
121 for (int i = 0; i < 10000; i++) |
|
122 al.add(Integer.valueOf(2 * i)); |
|
123 ll = new LinkedList(al); |
|
124 for (int i = 0; i < 500; i++) { |
162 for (int i = 0; i < 500; i++) { |
125 Integer key = Integer.valueOf(r1.nextInt(20000)); |
163 Integer key = Integer.valueOf(new Random(666).nextInt(20000)); |
126 if (Collections.binarySearch(al, key) != Collections |
164 assertEquals(Collections.binarySearch(l1, key), Collections |
127 .binarySearch(ll, key)) |
165 .binarySearch(l2, key), "Binary search failed: " + description); |
128 throw new Exception("Binary search failed: " + i); |
|
129 } |
166 } |
130 } |
167 } |
131 } |
168 } |