# HG changeset patch # User psandoz # Date 1395138278 -3600 # Node ID 221bf0e3642d93bc1bfb8423ae29b74f16dfd473 # Parent 013edb90a29dac2719e8197df4a1e844e6c5211a 8037106: Optimize Arrays.asList(...).forEach Reviewed-by: alanb, martin, mduigou, ulfzibis diff -r 013edb90a29d -r 221bf0e3642d jdk/src/share/classes/java/util/Arrays.java --- a/jdk/src/share/classes/java/util/Arrays.java Tue Mar 18 11:10:53 2014 +0100 +++ b/jdk/src/share/classes/java/util/Arrays.java Tue Mar 18 11:24:38 2014 +0100 @@ -28,6 +28,7 @@ import java.lang.reflect.Array; import java.util.concurrent.ForkJoinPool; import java.util.function.BinaryOperator; +import java.util.function.Consumer; import java.util.function.DoubleBinaryOperator; import java.util.function.IntBinaryOperator; import java.util.function.IntFunction; @@ -35,6 +36,7 @@ import java.util.function.IntToLongFunction; import java.util.function.IntUnaryOperator; import java.util.function.LongBinaryOperator; +import java.util.function.UnaryOperator; import java.util.stream.DoubleStream; import java.util.stream.IntStream; import java.util.stream.LongStream; @@ -3848,12 +3850,13 @@ @Override public int indexOf(Object o) { - if (o==null) { - for (int i=0; i spliterator() { return Spliterators.spliterator(a, Spliterator.ORDERED); } + + @Override + public void forEach(Consumer action) { + Objects.requireNonNull(action); + for (E e : a) { + action.accept(e); + } + } + + @Override + public void replaceAll(UnaryOperator operator) { + Objects.requireNonNull(operator); + E[] a = this.a; + for (int i = 0; i < a.length; i++) { + a[i] = operator.apply(a[i]); + } + } + + @Override + public void sort(Comparator c) { + Arrays.sort(a, c); + } } /** diff -r 013edb90a29d -r 221bf0e3642d jdk/test/java/util/Collection/CollectionDefaults.java --- a/jdk/test/java/util/Collection/CollectionDefaults.java Tue Mar 18 11:10:53 2014 +0100 +++ b/jdk/test/java/util/Collection/CollectionDefaults.java Tue Mar 18 11:24:38 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,6 +21,7 @@ * questions. */ +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -44,8 +45,8 @@ import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListMap; +import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.Supplier; /** * @test @@ -59,26 +60,25 @@ public static final Predicate pEven = x -> 0 == x % 2; public static final Predicate pOdd = x -> 1 == x % 2; - @SuppressWarnings("unchecked") - private static final Supplier[] TEST_CLASSES = { - // Collection - ExtendsAbstractCollection::new, + private static final List, Collection>> TEST_SUPPLIERS = Arrays.asList( + // Collection + ExtendsAbstractCollection::new, - // Lists - java.util.ArrayList::new, - java.util.LinkedList::new, - java.util.Vector::new, - java.util.concurrent.CopyOnWriteArrayList::new, - ExtendsAbstractList::new, + // Lists + java.util.ArrayList::new, + java.util.LinkedList::new, + java.util.Vector::new, + java.util.concurrent.CopyOnWriteArrayList::new, + ExtendsAbstractList::new, - // Sets - java.util.HashSet::new, - java.util.LinkedHashSet::new, - java.util.TreeSet::new, - java.util.concurrent.ConcurrentSkipListSet::new, - java.util.concurrent.CopyOnWriteArraySet::new, - ExtendsAbstractSet::new - }; + // Sets + java.util.HashSet::new, + java.util.LinkedHashSet::new, + java.util.TreeSet::new, + java.util.concurrent.ConcurrentSkipListSet::new, + java.util.concurrent.CopyOnWriteArraySet::new, + ExtendsAbstractSet::new + ); private static final int SIZE = 100; @@ -94,7 +94,7 @@ cases.add(new Object[] { new ExtendsAbstractSet<>() }); cases.add(new Object[] { Collections.newSetFromMap(new HashMap<>()) }); - cases.add(new Object[] { Collections.newSetFromMap(new LinkedHashMap()) }); + cases.add(new Object[] { Collections.newSetFromMap(new LinkedHashMap<>()) }); cases.add(new Object[] { Collections.newSetFromMap(new TreeMap<>()) }); cases.add(new Object[] { Collections.newSetFromMap(new ConcurrentHashMap<>()) }); cases.add(new Object[] { Collections.newSetFromMap(new ConcurrentSkipListMap<>()) }); @@ -107,24 +107,23 @@ } @Test(dataProvider = "setProvider") - public void testProvidedWithNull(final Set set) throws Exception { + public void testProvidedWithNull(final Set set) { try { set.forEach(null); fail("expected NPE not thrown"); - } catch (NullPointerException expected) { - ; // expected - } + } catch (NullPointerException expected) { // expected + } try { set.removeIf(null); fail("expected NPE not thrown"); - } catch (NullPointerException expected) { - ; // expected + } catch (NullPointerException expected) { // expected } } @Test - public void testForEach() throws Exception { - final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[]) TEST_CLASSES, SIZE); + public void testForEach() { + @SuppressWarnings("unchecked") + final CollectionSupplier> supplier = new CollectionSupplier(TEST_SUPPLIERS, SIZE); for (final CollectionSupplier.TestCase> test : supplier.get()) { final Collection original = test.expected; @@ -133,8 +132,7 @@ try { set.forEach(null); fail("expected NPE not thrown"); - } catch (NullPointerException expected) { - ; // expected + } catch (NullPointerException expected) { // expected } if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) { CollectionAsserts.assertContentsUnordered(set, original, test.toString()); @@ -155,8 +153,9 @@ } @Test - public void testRemoveIf() throws Exception { - final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[]) TEST_CLASSES, SIZE); + public void testRemoveIf() { + @SuppressWarnings("unchecked") + final CollectionSupplier> supplier = new CollectionSupplier(TEST_SUPPLIERS, SIZE); for (final CollectionSupplier.TestCase> test : supplier.get()) { final Collection original = test.expected; final Collection set = test.collection; @@ -164,8 +163,7 @@ try { set.removeIf(null); fail("expected NPE not thrown"); - } catch (NullPointerException expected) { - ; // expected + } catch (NullPointerException expected) { // expected } if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) { CollectionAsserts.assertContentsUnordered(set, original, test.toString()); diff -r 013edb90a29d -r 221bf0e3642d jdk/test/java/util/Collection/testlibrary/CollectionSupplier.java --- a/jdk/test/java/util/Collection/testlibrary/CollectionSupplier.java Tue Mar 18 11:10:53 2014 +0100 +++ b/jdk/test/java/util/Collection/testlibrary/CollectionSupplier.java Tue Mar 18 11:24:38 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ import java.lang.Integer; import java.lang.Iterable; import java.lang.Override; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -36,6 +37,7 @@ import java.util.Collection; import java.util.Collections; +import java.util.function.Function; import java.util.function.Supplier; /** @@ -44,20 +46,24 @@ */ public final class CollectionSupplier> implements Supplier>> { - private final Supplier[] classes; + private final List, C>> suppliers; private final int size; /** * A Collection test case. */ public static final class TestCase> { - /** * The name of the test case. */ public final String name; /** + * The supplier of a collection + */ + public Function, C> supplier; + + /** * Unmodifiable reference collection, useful for comparisons. */ public final List expected; @@ -71,11 +77,11 @@ * Create a Collection test case. * * @param name name of the test case - * @param expected reference collection * @param collection the modifiable test collection */ - public TestCase(String name, C collection) { + public TestCase(String name, Function, C> supplier, C collection) { this.name = name; + this.supplier = supplier; this.expected = Collections.unmodifiableList( Arrays.asList(collection.toArray(new Integer[0]))); this.collection = collection; @@ -107,54 +113,52 @@ } /** - * Create a {@code Supplier} that creates instances of specified collection - * classes of specified length. + * Create a {@code CollectionSupplier} that creates instances of specified + * collection suppliers of the specified size. * - * @param classNames class names that implement {@code Collection} + * @param suppliers the suppliers names that supply {@code Collection} + * instances * @param size the desired size of each collection */ - public CollectionSupplier(Supplier[] classes, int size) { - this.classes = Arrays.copyOf(classes, classes.length); + public CollectionSupplier(List, C>> suppliers, int size) { + this.suppliers = suppliers; this.size = size; } @Override public Iterable> get() { final Collection> cases = new LinkedList<>(); - for (final Supplier type : classes) { + for (final Function, C> supplier : suppliers) try { - final Collection empty = type.get(); - cases.add(new TestCase("empty", empty)); + cases.add(new TestCase<>("empty", supplier, supplier.apply(Collections.emptyList()))); - final Collection single = type.get(); - single.add(42); - cases.add(new TestCase("single", single)); + cases.add(new TestCase<>("single", supplier, supplier.apply(Arrays.asList(42)))); - final Collection regular = type.get(); + final Collection regular = new ArrayList<>(); for (int i = 0; i < size; i++) { regular.add(i); } - cases.add(new TestCase("regular", regular)); + cases.add(new TestCase<>("regular", supplier, supplier.apply(regular))); - final Collection reverse = type.get(); + final Collection reverse = new ArrayList<>(); for (int i = size; i >= 0; i--) { reverse.add(i); } - cases.add(new TestCase("reverse", reverse)); + cases.add(new TestCase<>("reverse", supplier, supplier.apply(reverse))); - final Collection odds = type.get(); + final Collection odds = new ArrayList<>(); for (int i = 0; i < size; i++) { odds.add((i * 2) + 1); } - cases.add(new TestCase("odds", odds)); + cases.add(new TestCase<>("odds", supplier, supplier.apply(odds))); - final Collection evens = type.get(); + final Collection evens = new ArrayList<>(); for (int i = 0; i < size; i++) { evens.add(i * 2); } - cases.add(new TestCase("evens", evens)); + cases.add(new TestCase<>("evens", supplier, supplier.apply(evens))); - final Collection fibonacci = type.get(); + final Collection fibonacci = new ArrayList<>(); int prev2 = 0; int prev1 = 1; for (int i = 0; i < size; i++) { @@ -166,58 +170,62 @@ prev2 = prev1; prev1 = n; } - cases.add(new TestCase("fibonacci", fibonacci)); + cases.add(new TestCase<>("fibonacci", supplier, supplier.apply(fibonacci))); + - // variants where the size of the backing storage != reported size + boolean isStructurallyModifiable = false; + try { + C t = supplier.apply(Collections.emptyList()); + t.add(1); + isStructurallyModifiable = true; + } catch (UnsupportedOperationException e) { } + + if (!isStructurallyModifiable) + continue; + + + // variants where the size of the backing storage != reported size // created by removing half of the elements - final Collection emptyWithSlack = type.get(); + final C emptyWithSlack = supplier.apply(Collections.emptyList()); emptyWithSlack.add(42); assertTrue(emptyWithSlack.remove(42)); - cases.add(new TestCase("emptyWithSlack", emptyWithSlack)); + cases.add(new TestCase<>("emptyWithSlack", supplier, emptyWithSlack)); - final Collection singleWithSlack = type.get(); + final C singleWithSlack = supplier.apply(Collections.emptyList()); singleWithSlack.add(42); singleWithSlack.add(43); assertTrue(singleWithSlack.remove(43)); - cases.add(new TestCase("singleWithSlack", singleWithSlack)); + cases.add(new TestCase<>("singleWithSlack", supplier, singleWithSlack)); - final Collection regularWithSlack = type.get(); + final C regularWithSlack = supplier.apply(Collections.emptyList()); for (int i = 0; i < (2 * size); i++) { regularWithSlack.add(i); } - assertTrue(regularWithSlack.removeIf((x) -> { - return x >= size; - })); - cases.add(new TestCase("regularWithSlack", regularWithSlack)); + assertTrue(regularWithSlack.removeIf(x -> x < size)); + cases.add(new TestCase<>("regularWithSlack", supplier, regularWithSlack)); - final Collection reverseWithSlack = type.get(); + final C reverseWithSlack = supplier.apply(Collections.emptyList()); for (int i = 2 * size; i >= 0; i--) { reverseWithSlack.add(i); } - assertTrue(reverseWithSlack.removeIf((x) -> { - return x < size; - })); - cases.add(new TestCase("reverseWithSlack", reverseWithSlack)); + assertTrue(reverseWithSlack.removeIf(x -> x < size)); + cases.add(new TestCase<>("reverseWithSlack", supplier, reverseWithSlack)); - final Collection oddsWithSlack = type.get(); + final C oddsWithSlack = supplier.apply(Collections.emptyList()); for (int i = 0; i < 2 * size; i++) { oddsWithSlack.add((i * 2) + 1); } - assertTrue(oddsWithSlack.removeIf((x) -> { - return x >= size; - })); - cases.add(new TestCase("oddsWithSlack", oddsWithSlack)); + assertTrue(oddsWithSlack.removeIf(x -> x >= size)); + cases.add(new TestCase<>("oddsWithSlack", supplier, oddsWithSlack)); - final Collection evensWithSlack = type.get(); + final C evensWithSlack = supplier.apply(Collections.emptyList()); for (int i = 0; i < 2 * size; i++) { evensWithSlack.add(i * 2); } - assertTrue(evensWithSlack.removeIf((x) -> { - return x >= size; - })); - cases.add(new TestCase("evensWithSlack", evensWithSlack)); + assertTrue(evensWithSlack.removeIf(x -> x >= size)); + cases.add(new TestCase<>("evensWithSlack", supplier, evensWithSlack)); - final Collection fibonacciWithSlack = type.get(); + final C fibonacciWithSlack = supplier.apply(Collections.emptyList()); prev2 = 0; prev1 = 1; for (int i = 0; i < size; i++) { @@ -229,15 +237,12 @@ prev2 = prev1; prev1 = n; } - assertTrue(fibonacciWithSlack.removeIf((x) -> { - return x < 20; - })); - cases.add(new TestCase("fibonacciWithSlack", - fibonacciWithSlack)); - } catch (Exception failed) { + assertTrue(fibonacciWithSlack.removeIf(x -> x < 20)); + cases.add(new TestCase<>("fibonacciWithSlack", supplier, fibonacciWithSlack)); + } + catch (Exception failed) { throw new TestException(failed); } - } return cases; } diff -r 013edb90a29d -r 221bf0e3642d jdk/test/java/util/List/ListDefaults.java --- a/jdk/test/java/util/List/ListDefaults.java Tue Mar 18 11:10:53 2014 +0100 +++ b/jdk/test/java/util/List/ListDefaults.java Tue Mar 18 11:24:38 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -43,31 +44,45 @@ import java.lang.reflect.Constructor; import java.util.ConcurrentModificationException; +import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; /** * @test * @summary Unit tests for extension methods on List - * @bug 8023367 + * @bug 8023367 8037106 * @library ../Collection/testlibrary * @build CollectionAsserts CollectionSupplier ExtendsAbstractList * @run testng ListDefaults */ public class ListDefaults { - private static final Supplier[] LIST_CLASSES = { - java.util.ArrayList::new, - java.util.LinkedList::new, - java.util.Vector::new, - java.util.concurrent.CopyOnWriteArrayList::new, - ExtendsAbstractList::new - }; + // Suppliers of lists that can support structural modifications + private static final List> LIST_STRUCT_MOD_SUPPLIERS = Arrays.asList( + java.util.ArrayList::new, + java.util.LinkedList::new, + java.util.Vector::new, + java.util.concurrent.CopyOnWriteArrayList::new, + ExtendsAbstractList::new + ); - private static final Supplier[] LIST_CME_CLASSES = { - java.util.ArrayList::new, - java.util.Vector::new - }; + // Suppliers of lists that can support in place modifications + private static final List> LIST_SUPPLIERS = Arrays.asList( + java.util.ArrayList::new, + java.util.LinkedList::new, + java.util.Vector::new, + java.util.concurrent.CopyOnWriteArrayList::new, + ExtendsAbstractList::new, + c -> Arrays.asList(c.toArray()) + ); + + // Suppliers of lists supporting CMEs + private static final List> LIST_CME_SUPPLIERS = Arrays.asList( + java.util.ArrayList::new, + java.util.Vector::new + ); private static final Predicate pEven = x -> 0 == x % 2; private static final Predicate pOdd = x -> 1 == x % 2; @@ -83,17 +98,13 @@ private static final int SUBLIST_TO = SIZE - 5; private static final int SUBLIST_SIZE = SUBLIST_TO - SUBLIST_FROM; - private static interface Callback { - void call(List list); - } - // call the callback for each recursive subList - private void trimmedSubList(final List list, final Callback callback) { + private void trimmedSubList(final List list, final Consumer> callback) { int size = list.size(); if (size > 1) { // trim 1 element from both ends final List subList = list.subList(1, size - 1); - callback.call(subList); + callback.accept(subList); trimmedSubList(subList, callback); } } @@ -107,17 +118,21 @@ cases.add(new Object[] { new Vector<>() }); cases.add(new Object[] { new Stack<>() }); cases.add(new Object[] { new CopyOnWriteArrayList<>() }); + cases.add(new Object[] { Arrays.asList() }); - cases.add(new Object[] { new ArrayList(){{add(42);}} }); - cases.add(new Object[] { new LinkedList(){{add(42);}} }); - cases.add(new Object[] { new Vector(){{add(42);}} }); - cases.add(new Object[] { new Stack(){{add(42);}} }); - cases.add(new Object[] { new CopyOnWriteArrayList(){{add(42);}} }); + List l = Arrays.asList(42); + cases.add(new Object[] { new ArrayList<>(l) }); + cases.add(new Object[] { new LinkedList<>(l) }); + cases.add(new Object[] { new Vector<>(l) }); + Stack s = new Stack<>(); s.addAll(l); + cases.add(new Object[]{s}); + cases.add(new Object[] { new CopyOnWriteArrayList<>(l) }); + cases.add(new Object[] { l }); return cases.toArray(new Object[0][cases.size()]); } @Test(dataProvider = "listProvider") - public void testProvidedWithNull(final List list) throws Exception { + public void testProvidedWithNull(final List list) { try { list.forEach(null); fail("expected NPE not thrown"); @@ -138,11 +153,12 @@ } @Test - public void testForEach() throws Exception { - final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CLASSES, SIZE); + public void testForEach() { + @SuppressWarnings("unchecked") + final CollectionSupplier> supplier = new CollectionSupplier(LIST_SUPPLIERS, SIZE); for (final CollectionSupplier.TestCase> test : supplier.get()) { - final List original = ((List) test.expected); - final List list = ((List) test.collection); + final List original = test.expected; + final List list = test.collection; try { list.forEach(null); @@ -165,23 +181,21 @@ } } - trimmedSubList(list, new Callback() { - @Override - public void call(final List list) { - final List actual = new LinkedList<>(); - list.forEach(actual::add); - CollectionAsserts.assertContents(actual, list); - } - }); + trimmedSubList(list, l -> { + final List a = new LinkedList<>(); + l.forEach(a::add); + CollectionAsserts.assertContents(a, l); + }); } } @Test - public void testRemoveIf() throws Exception { - final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CLASSES, SIZE); + public void testRemoveIf() { + @SuppressWarnings("unchecked") + final CollectionSupplier> supplier = new CollectionSupplier(LIST_STRUCT_MOD_SUPPLIERS, SIZE); for (final CollectionSupplier.TestCase> test : supplier.get()) { - final List original = ((List) test.expected); - final List list = ((List) test.collection); + final List original = test.expected; + final List list = test.collection; try { list.removeIf(null); @@ -195,9 +209,9 @@ } } - for (final CollectionSupplier.TestCase test : supplier.get()) { - final List original = ((List) test.expected); - final List list = ((List) test.collection); + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final List original = test.expected; + final List list = test.collection; list.removeIf(pOdd); for (int i : list) { assertTrue((i % 2) == 0); @@ -211,9 +225,9 @@ assertTrue(list.isEmpty()); } - for (final CollectionSupplier.TestCase test : supplier.get()) { - final List original = ((List) test.expected); - final List list = ((List) test.collection); + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final List original = test.expected; + final List list = test.collection; final List listCopy = new ArrayList<>(list); if (original.size() > SUBLIST_SIZE) { final List subList = list.subList(SUBLIST_FROM, SUBLIST_TO); @@ -237,22 +251,19 @@ } } - for (final CollectionSupplier.TestCase test : supplier.get()) { - final List list = ((List) test.collection); - trimmedSubList(list, new Callback() { - @Override - public void call(final List list) { - final List copy = new ArrayList<>(list); - list.removeIf(pOdd); - for (int i : list) { - assertTrue((i % 2) == 0); - } - for (int i : copy) { - if (i % 2 == 0) { - assertTrue(list.contains(i)); - } else { - assertFalse(list.contains(i)); - } + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final List list = test.collection; + trimmedSubList(list, l -> { + final List copy = new ArrayList<>(l); + l.removeIf(pOdd); + for (int i : l) { + assertTrue((i % 2) == 0); + } + for (int i : copy) { + if (i % 2 == 0) { + assertTrue(l.contains(i)); + } else { + assertFalse(l.contains(i)); } } }); @@ -267,12 +278,13 @@ } @Test - public void testReplaceAll() throws Exception { + public void testReplaceAll() { final int scale = 3; - final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CLASSES, SIZE); + @SuppressWarnings("unchecked") + final CollectionSupplier> supplier = new CollectionSupplier(LIST_SUPPLIERS, SIZE); for (final CollectionSupplier.TestCase> test : supplier.get()) { - final List original = ((List) test.expected); - final List list = ((List) test.collection); + final List original = test.expected; + final List list = test.collection; try { list.replaceAll(null); @@ -281,7 +293,7 @@ CollectionAsserts.assertContents(list, original); list.replaceAll(x -> scale * x); - for (int i=0; i < original.size(); i++) { + for (int i = 0; i < original.size(); i++) { assertTrue(list.get(i) == (scale * original.get(i)), "mismatch at index " + i); } @@ -306,28 +318,26 @@ } } - for (final CollectionSupplier.TestCase test : supplier.get()) { - final List list = ((List) test.collection); - trimmedSubList(list, new Callback() { - @Override - public void call(final List list) { - final List copy = new ArrayList<>(list); - final int offset = 5; - list.replaceAll(x -> offset + x); - for (int i=0; i < copy.size(); i++) { - assertTrue(list.get(i) == (offset + copy.get(i)), "mismatch at index " + i); - } + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final List list = test.collection; + trimmedSubList(list, l -> { + final List copy = new ArrayList<>(l); + final int offset = 5; + l.replaceAll(x -> offset + x); + for (int i = 0; i < copy.size(); i++) { + assertTrue(l.get(i) == (offset + copy.get(i)), "mismatch at index " + i); } }); } } @Test - public void testSort() throws Exception { - final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CLASSES, SIZE); + public void testSort() { + @SuppressWarnings("unchecked") + final CollectionSupplier> supplier = new CollectionSupplier(LIST_SUPPLIERS, SIZE); for (final CollectionSupplier.TestCase> test : supplier.get()) { - final List original = ((List) test.expected); - final List list = ((List) test.collection); + final List original = test.expected; + final List list = test.collection; CollectionSupplier.shuffle(list); list.sort(Integer::compare); CollectionAsserts.assertSorted(list, Integer::compare); @@ -338,23 +348,23 @@ CollectionSupplier.shuffle(list); list.sort(null); - CollectionAsserts.assertSorted(list, Comparator.naturalOrder()); + CollectionAsserts.assertSorted(list, Comparator.naturalOrder()); if (test.name.startsWith("reverse")) { Collections.reverse(list); } CollectionAsserts.assertContents(list, original); CollectionSupplier.shuffle(list); - list.sort(Comparator.naturalOrder()); - CollectionAsserts.assertSorted(list, Comparator.naturalOrder()); + list.sort(Comparator.naturalOrder()); + CollectionAsserts.assertSorted(list, Comparator.naturalOrder()); if (test.name.startsWith("reverse")) { Collections.reverse(list); } CollectionAsserts.assertContents(list, original); CollectionSupplier.shuffle(list); - list.sort(Comparator.reverseOrder()); - CollectionAsserts.assertSorted(list, Comparator.reverseOrder()); + list.sort(Comparator.reverseOrder()); + CollectionAsserts.assertSorted(list, Comparator.reverseOrder()); if (!test.name.startsWith("reverse")) { Collections.reverse(list); } @@ -365,32 +375,35 @@ CollectionAsserts.assertSorted(list, BIT_COUNT_COMPARATOR); // check sort by verifying that bitCount increases and never drops int minBitCount = 0; - int bitCount = 0; for (final Integer i : list) { - bitCount = Integer.bitCount(i); + int bitCount = Integer.bitCount(i); assertTrue(bitCount >= minBitCount); minBitCount = bitCount; } + // Resuse the supplier to store AtomicInteger instead of Integer + // Hence the use of raw type and cast + List incomparablesData = new ArrayList<>(); + for (int i = 0; i < test.expected.size(); i++) { + incomparablesData.add(new AtomicInteger(i)); + } + Function f = test.supplier; @SuppressWarnings("unchecked") - final Constructor> defaultConstructor = ((Class>)test.collection.getClass()).getConstructor(); - final List incomparables = (List) defaultConstructor.newInstance(); + List incomparables = (List) f.apply(incomparablesData); - for (int i=0; i < test.expected.size(); i++) { - incomparables.add(new AtomicInteger(i)); - } CollectionSupplier.shuffle(incomparables); incomparables.sort(ATOMIC_INTEGER_COMPARATOR); - for (int i=0; i < test.expected.size(); i++) { + for (int i = 0; i < test.expected.size(); i++) { assertEquals(i, incomparables.get(i).intValue()); } + if (original.size() > SUBLIST_SIZE) { final List copy = new ArrayList<>(list); final List subList = list.subList(SUBLIST_FROM, SUBLIST_TO); CollectionSupplier.shuffle(subList); - subList.sort(Comparator.naturalOrder()); - CollectionAsserts.assertSorted(subList, Comparator.naturalOrder()); + subList.sort(Comparator.naturalOrder()); + CollectionAsserts.assertSorted(subList, Comparator.naturalOrder()); // verify that elements [0, from) remain unmodified for (int i = 0; i < SUBLIST_FROM; i++) { assertTrue(list.get(i) == copy.get(i), @@ -404,25 +417,22 @@ } } - for (final CollectionSupplier.TestCase test : supplier.get()) { - final List list = ((List) test.collection); - trimmedSubList(list, new Callback() { - @Override - public void call(final List list) { - final List copy = new ArrayList<>(list); - CollectionSupplier.shuffle(list); - list.sort(Comparator.naturalOrder()); - CollectionAsserts.assertSorted(list, Comparator.naturalOrder()); - } + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final List list = test.collection; + trimmedSubList(list, l -> { + CollectionSupplier.shuffle(l); + l.sort(Comparator.naturalOrder()); + CollectionAsserts.assertSorted(l, Comparator.naturalOrder()); }); } } @Test - public void testForEachThrowsCME() throws Exception { - final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CME_CLASSES, SIZE); + public void testForEachThrowsCME() { + @SuppressWarnings("unchecked") + final CollectionSupplier> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE); for (final CollectionSupplier.TestCase> test : supplier.get()) { - final List list = ((List) test.collection); + final List list = test.collection; if (list.size() <= 1) { continue; @@ -430,7 +440,7 @@ boolean gotException = false; try { // bad predicate that modifies its list, should throw CME - list.forEach((x) -> {list.add(x);}); + list.forEach(list::add); } catch (ConcurrentModificationException cme) { gotException = true; } @@ -441,11 +451,11 @@ } @Test - public void testRemoveIfThrowsCME() throws Exception { - final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CME_CLASSES, SIZE); + public void testRemoveIfThrowsCME() { + @SuppressWarnings("unchecked") + final CollectionSupplier> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE); for (final CollectionSupplier.TestCase> test : supplier.get()) { - final List original = ((List) test.expected); - final List list = ((List) test.collection); + final List list = test.collection; if (list.size() <= 1) { continue; @@ -453,7 +463,7 @@ boolean gotException = false; try { // bad predicate that modifies its list, should throw CME - list.removeIf((x) -> {return list.add(x);}); + list.removeIf(list::add); } catch (ConcurrentModificationException cme) { gotException = true; } @@ -464,10 +474,11 @@ } @Test - public void testReplaceAllThrowsCME() throws Exception { - final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CME_CLASSES, SIZE); + public void testReplaceAllThrowsCME() { + @SuppressWarnings("unchecked") + final CollectionSupplier> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE); for (final CollectionSupplier.TestCase> test : supplier.get()) { - final List list = ((List) test.collection); + final List list = test.collection; if (list.size() <= 1) { continue; @@ -486,10 +497,11 @@ } @Test - public void testSortThrowsCME() throws Exception { - final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CME_CLASSES, SIZE); + public void testSortThrowsCME() { + @SuppressWarnings("unchecked") + final CollectionSupplier> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE); for (final CollectionSupplier.TestCase> test : supplier.get()) { - final List list = ((List) test.collection); + final List list = test.collection; if (list.size() <= 1) { continue; @@ -523,7 +535,7 @@ } @Test(dataProvider = "shortIntListProvider") - public void testRemoveIfFromSlice(final List list) throws Exception { + public void testRemoveIfFromSlice(final List list) { final List sublist = list.subList(3, 6); assertTrue(sublist.removeIf(x -> x == 4)); CollectionAsserts.assertContents(list, SLICED_EXPECTED);