Path: blob/master/test/jdk/java/util/List/ListDefaults.java
41149 views
/*1* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.util.ArrayList;24import java.util.Arrays;25import java.util.Collection;26import java.util.Collections;27import java.util.Comparator;28import java.util.List;29import java.util.LinkedList;30import java.util.Stack;31import java.util.Vector;32import java.util.concurrent.CopyOnWriteArrayList;33import java.util.concurrent.atomic.AtomicBoolean;34import java.util.concurrent.atomic.AtomicInteger;3536import org.testng.annotations.DataProvider;37import org.testng.annotations.Test;3839import static org.testng.Assert.assertEquals;40import static org.testng.Assert.assertFalse;41import static org.testng.Assert.assertTrue;42import static org.testng.Assert.fail;4344import java.util.ConcurrentModificationException;45import java.util.function.Consumer;46import java.util.function.Function;47import java.util.function.Predicate;4849/**50* @test51* @summary Unit tests for extension methods on List52* @bug 8023367 803710653* @library ../Collection/testlibrary54* @build CollectionAsserts CollectionSupplier ExtendsAbstractList55* @run testng ListDefaults56*/57public class ListDefaults {5859// Suppliers of lists that can support structural modifications60private static final List<Function<Collection, List>> LIST_STRUCT_MOD_SUPPLIERS = Arrays.asList(61java.util.ArrayList::new,62java.util.LinkedList::new,63java.util.Vector::new,64java.util.concurrent.CopyOnWriteArrayList::new,65ExtendsAbstractList::new66);6768// Suppliers of lists that can support in place modifications69private static final List<Function<Collection, List>> LIST_SUPPLIERS = Arrays.asList(70java.util.ArrayList::new,71java.util.LinkedList::new,72java.util.Vector::new,73java.util.concurrent.CopyOnWriteArrayList::new,74ExtendsAbstractList::new,75c -> Arrays.asList(c.toArray())76);7778// Suppliers of lists supporting CMEs79private static final List<Function<Collection, List>> LIST_CME_SUPPLIERS = Arrays.asList(80java.util.ArrayList::new,81java.util.Vector::new82);8384private static final Predicate<Integer> pEven = x -> 0 == x % 2;85private static final Predicate<Integer> pOdd = x -> 1 == x % 2;8687private static final Comparator<Integer> BIT_COUNT_COMPARATOR =88(x, y) -> Integer.bitCount(x) - Integer.bitCount(y);8990private static final Comparator<AtomicInteger> ATOMIC_INTEGER_COMPARATOR =91(x, y) -> x.intValue() - y.intValue();9293private static final int SIZE = 100;94private static final int SUBLIST_FROM = 20;95private static final int SUBLIST_TO = SIZE - 5;96private static final int SUBLIST_SIZE = SUBLIST_TO - SUBLIST_FROM;9798// call the callback for each recursive subList99private void trimmedSubList(final List<Integer> list, final Consumer<List<Integer>> callback) {100int size = list.size();101if (size > 1) {102// trim 1 element from both ends103final List<Integer> subList = list.subList(1, size - 1);104callback.accept(subList);105trimmedSubList(subList, callback);106}107}108109@DataProvider(name="listProvider", parallel=true)110public static Object[][] listCases() {111final List<Object[]> cases = new LinkedList<>();112cases.add(new Object[] { Collections.emptyList() });113cases.add(new Object[] { new ArrayList<>() });114cases.add(new Object[] { new LinkedList<>() });115cases.add(new Object[] { new Vector<>() });116cases.add(new Object[] { new Stack<>() });117cases.add(new Object[] { new CopyOnWriteArrayList<>() });118cases.add(new Object[] { Arrays.asList() });119120List<Integer> l = Arrays.asList(42);121cases.add(new Object[] { new ArrayList<>(l) });122cases.add(new Object[] { new LinkedList<>(l) });123cases.add(new Object[] { new Vector<>(l) });124Stack<Integer> s = new Stack<>(); s.addAll(l);125cases.add(new Object[]{s});126cases.add(new Object[] { new CopyOnWriteArrayList<>(l) });127cases.add(new Object[] { l });128return cases.toArray(new Object[0][cases.size()]);129}130131@Test(dataProvider = "listProvider")132public void testProvidedWithNull(final List<Integer> list) {133try {134list.forEach(null);135fail("expected NPE not thrown");136} catch (NullPointerException npe) {}137try {138list.replaceAll(null);139fail("expected NPE not thrown");140} catch (NullPointerException npe) {}141try {142list.removeIf(null);143fail("expected NPE not thrown");144} catch (NullPointerException npe) {}145try {146list.sort(null);147} catch (Throwable t) {148fail("Exception not expected: " + t);149}150}151152@Test153public void testForEach() {154@SuppressWarnings("unchecked")155final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_SUPPLIERS, SIZE);156for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {157final List<Integer> original = test.expected;158final List<Integer> list = test.collection;159160try {161list.forEach(null);162fail("expected NPE not thrown");163} catch (NullPointerException npe) {}164CollectionAsserts.assertContents(list, original);165166final List<Integer> actual = new LinkedList<>();167list.forEach(actual::add);168CollectionAsserts.assertContents(actual, list);169CollectionAsserts.assertContents(actual, original);170171if (original.size() > SUBLIST_SIZE) {172final List<Integer> subList = original.subList(SUBLIST_FROM, SUBLIST_TO);173final List<Integer> actualSubList = new LinkedList<>();174subList.forEach(actualSubList::add);175assertEquals(actualSubList.size(), SUBLIST_SIZE);176for (int i = 0; i < SUBLIST_SIZE; i++) {177assertEquals(actualSubList.get(i), original.get(i + SUBLIST_FROM));178}179}180181trimmedSubList(list, l -> {182final List<Integer> a = new LinkedList<>();183l.forEach(a::add);184CollectionAsserts.assertContents(a, l);185});186}187}188189@Test190public void testRemoveIf() {191@SuppressWarnings("unchecked")192final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_STRUCT_MOD_SUPPLIERS, SIZE);193for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {194final List<Integer> original = test.expected;195final List<Integer> list = test.collection;196197try {198list.removeIf(null);199fail("expected NPE not thrown");200} catch (NullPointerException npe) {}201CollectionAsserts.assertContents(list, original);202203final AtomicInteger offset = new AtomicInteger(1);204while (list.size() > 0) {205removeFirst(original, list, offset);206}207}208209for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {210final List<Integer> original = test.expected;211final List<Integer> list = test.collection;212list.removeIf(pOdd);213for (int i : list) {214assertTrue((i % 2) == 0);215}216for (int i : original) {217if (i % 2 == 0) {218assertTrue(list.contains(i));219}220}221list.removeIf(pEven);222assertTrue(list.isEmpty());223}224225for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {226final List<Integer> original = test.expected;227final List<Integer> list = test.collection;228final List<Integer> listCopy = new ArrayList<>(list);229if (original.size() > SUBLIST_SIZE) {230final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);231final List<Integer> subListCopy = new ArrayList<>(subList);232listCopy.removeAll(subList);233subList.removeIf(pOdd);234for (int i : subList) {235assertTrue((i % 2) == 0);236}237for (int i : subListCopy) {238if (i % 2 == 0) {239assertTrue(subList.contains(i));240} else {241assertFalse(subList.contains(i));242}243}244subList.removeIf(pEven);245assertTrue(subList.isEmpty());246// elements outside the view should remain247CollectionAsserts.assertContents(list, listCopy);248}249}250251for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {252final List<Integer> list = test.collection;253trimmedSubList(list, l -> {254final List<Integer> copy = new ArrayList<>(l);255l.removeIf(pOdd);256for (int i : l) {257assertTrue((i % 2) == 0);258}259for (int i : copy) {260if (i % 2 == 0) {261assertTrue(l.contains(i));262} else {263assertFalse(l.contains(i));264}265}266});267}268}269270// remove the first element271private void removeFirst(final List<Integer> original, final List<Integer> list, final AtomicInteger offset) {272final AtomicBoolean first = new AtomicBoolean(true);273list.removeIf(x -> first.getAndSet(false));274CollectionAsserts.assertContents(original.subList(offset.getAndIncrement(), original.size()), list);275}276277@Test278public void testReplaceAll() {279final int scale = 3;280@SuppressWarnings("unchecked")281final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_SUPPLIERS, SIZE);282for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {283final List<Integer> original = test.expected;284final List<Integer> list = test.collection;285286try {287list.replaceAll(null);288fail("expected NPE not thrown");289} catch (NullPointerException npe) {}290CollectionAsserts.assertContents(list, original);291292list.replaceAll(x -> scale * x);293for (int i = 0; i < original.size(); i++) {294assertTrue(list.get(i) == (scale * original.get(i)), "mismatch at index " + i);295}296297if (original.size() > SUBLIST_SIZE) {298final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);299subList.replaceAll(x -> x + 1);300// verify elements in view [from, to) were replaced301for (int i = 0; i < SUBLIST_SIZE; i++) {302assertTrue(subList.get(i) == ((scale * original.get(i + SUBLIST_FROM)) + 1),303"mismatch at sublist index " + i);304}305// verify that elements [0, from) remain unmodified306for (int i = 0; i < SUBLIST_FROM; i++) {307assertTrue(list.get(i) == (scale * original.get(i)),308"mismatch at original index " + i);309}310// verify that elements [to, size) remain unmodified311for (int i = SUBLIST_TO; i < list.size(); i++) {312assertTrue(list.get(i) == (scale * original.get(i)),313"mismatch at original index " + i);314}315}316}317318for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {319final List<Integer> list = test.collection;320trimmedSubList(list, l -> {321final List<Integer> copy = new ArrayList<>(l);322final int offset = 5;323l.replaceAll(x -> offset + x);324for (int i = 0; i < copy.size(); i++) {325assertTrue(l.get(i) == (offset + copy.get(i)), "mismatch at index " + i);326}327});328}329}330331@Test332public void testSort() {333@SuppressWarnings("unchecked")334final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_SUPPLIERS, SIZE);335for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {336final List<Integer> original = test.expected;337final List<Integer> list = test.collection;338CollectionSupplier.shuffle(list);339list.sort(Integer::compare);340CollectionAsserts.assertSorted(list, Integer::compare);341if (test.name.startsWith("reverse")) {342Collections.reverse(list);343}344CollectionAsserts.assertContents(list, original);345346CollectionSupplier.shuffle(list);347list.sort(null);348CollectionAsserts.assertSorted(list, Comparator.naturalOrder());349if (test.name.startsWith("reverse")) {350Collections.reverse(list);351}352CollectionAsserts.assertContents(list, original);353354CollectionSupplier.shuffle(list);355list.sort(Comparator.naturalOrder());356CollectionAsserts.assertSorted(list, Comparator.naturalOrder());357if (test.name.startsWith("reverse")) {358Collections.reverse(list);359}360CollectionAsserts.assertContents(list, original);361362CollectionSupplier.shuffle(list);363list.sort(Comparator.reverseOrder());364CollectionAsserts.assertSorted(list, Comparator.reverseOrder());365if (!test.name.startsWith("reverse")) {366Collections.reverse(list);367}368CollectionAsserts.assertContents(list, original);369370CollectionSupplier.shuffle(list);371list.sort(BIT_COUNT_COMPARATOR);372CollectionAsserts.assertSorted(list, BIT_COUNT_COMPARATOR);373// check sort by verifying that bitCount increases and never drops374int minBitCount = 0;375for (final Integer i : list) {376int bitCount = Integer.bitCount(i);377assertTrue(bitCount >= minBitCount);378minBitCount = bitCount;379}380381// Reuse the supplier to store AtomicInteger instead of Integer382// Hence the use of raw type and cast383List<AtomicInteger> incomparablesData = new ArrayList<>();384for (int i = 0; i < test.expected.size(); i++) {385incomparablesData.add(new AtomicInteger(i));386}387Function f = test.supplier;388@SuppressWarnings("unchecked")389List<AtomicInteger> incomparables = (List<AtomicInteger>) f.apply(incomparablesData);390391CollectionSupplier.shuffle(incomparables);392incomparables.sort(ATOMIC_INTEGER_COMPARATOR);393for (int i = 0; i < test.expected.size(); i++) {394assertEquals(i, incomparables.get(i).intValue());395}396397398if (original.size() > SUBLIST_SIZE) {399final List<Integer> copy = new ArrayList<>(list);400final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);401CollectionSupplier.shuffle(subList);402subList.sort(Comparator.naturalOrder());403CollectionAsserts.assertSorted(subList, Comparator.naturalOrder());404// verify that elements [0, from) remain unmodified405for (int i = 0; i < SUBLIST_FROM; i++) {406assertTrue(list.get(i) == copy.get(i),407"mismatch at index " + i);408}409// verify that elements [to, size) remain unmodified410for (int i = SUBLIST_TO; i < list.size(); i++) {411assertTrue(list.get(i) == copy.get(i),412"mismatch at index " + i);413}414}415}416417for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {418final List<Integer> list = test.collection;419trimmedSubList(list, l -> {420CollectionSupplier.shuffle(l);421l.sort(Comparator.naturalOrder());422CollectionAsserts.assertSorted(l, Comparator.naturalOrder());423});424}425}426427@Test428public void testForEachThrowsCME() {429@SuppressWarnings("unchecked")430final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE);431for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {432final List<Integer> list = test.collection;433434if (list.size() <= 1) {435continue;436}437boolean gotException = false;438try {439// bad predicate that modifies its list, should throw CME440list.forEach(list::add);441} catch (ConcurrentModificationException cme) {442gotException = true;443}444if (!gotException) {445fail("expected CME was not thrown from " + test);446}447}448}449450@Test451public void testRemoveIfThrowsCME() {452@SuppressWarnings("unchecked")453final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE);454for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {455final List<Integer> list = test.collection;456457if (list.size() <= 1) {458continue;459}460boolean gotException = false;461try {462// bad predicate that modifies its list, should throw CME463list.removeIf(list::add);464} catch (ConcurrentModificationException cme) {465gotException = true;466}467if (!gotException) {468fail("expected CME was not thrown from " + test);469}470}471}472473@Test474public void testReplaceAllThrowsCME() {475@SuppressWarnings("unchecked")476final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE);477for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {478final List<Integer> list = test.collection;479480if (list.size() <= 1) {481continue;482}483boolean gotException = false;484try {485// bad predicate that modifies its list, should throw CME486list.replaceAll(x -> {int n = 3 * x; list.add(n); return n;});487} catch (ConcurrentModificationException cme) {488gotException = true;489}490if (!gotException) {491fail("expected CME was not thrown from " + test);492}493}494}495496@Test497public void testSortThrowsCME() {498@SuppressWarnings("unchecked")499final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE);500for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {501final List<Integer> list = test.collection;502503if (list.size() <= 1) {504continue;505}506boolean gotException = false;507try {508// bad predicate that modifies its list, should throw CME509list.sort((x, y) -> {list.add(x); return x - y;});510} catch (ConcurrentModificationException cme) {511gotException = true;512}513if (!gotException) {514fail("expected CME was not thrown from " + test);515}516}517}518519private static final List<Integer> SLICED_EXPECTED = Arrays.asList(0, 1, 2, 3, 5, 6, 7, 8, 9);520private static final List<Integer> SLICED_EXPECTED2 = Arrays.asList(0, 1, 2, 5, 6, 7, 8, 9);521522@DataProvider(name="shortIntListProvider", parallel=true)523public static Object[][] intListCases() {524final Integer[] DATA = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};525final List<Object[]> cases = new LinkedList<>();526cases.add(new Object[] { new ArrayList<>(Arrays.asList(DATA)) });527cases.add(new Object[] { new LinkedList<>(Arrays.asList(DATA)) });528cases.add(new Object[] { new Vector<>(Arrays.asList(DATA)) });529cases.add(new Object[] { new CopyOnWriteArrayList<>(Arrays.asList(DATA)) });530cases.add(new Object[] { new ExtendsAbstractList<>(Arrays.asList(DATA)) });531return cases.toArray(new Object[0][cases.size()]);532}533534@Test(dataProvider = "shortIntListProvider")535public void testRemoveIfFromSlice(final List<Integer> list) {536final List<Integer> sublist = list.subList(3, 6);537assertTrue(sublist.removeIf(x -> x == 4));538CollectionAsserts.assertContents(list, SLICED_EXPECTED);539540final List<Integer> sublist2 = list.subList(2, 5);541assertTrue(sublist2.removeIf(x -> x == 3));542CollectionAsserts.assertContents(list, SLICED_EXPECTED2);543}544}545546547