/* * Copyright 2015 Goldman Sachs. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gs.collections.impl.list.mutable; import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; import java.util.RandomAccess; import com.gs.collections.api.list.MutableList; import com.gs.collections.impl.block.factory.IntegerPredicates; import com.gs.collections.impl.block.factory.Predicates; import com.gs.collections.impl.block.procedure.CollectionAddProcedure; import com.gs.collections.impl.factory.Lists; import com.gs.collections.impl.list.Interval; import com.gs.collections.impl.parallel.ParallelIterate; import com.gs.collections.impl.test.Verify; import org.junit.Assert; import org.junit.Test; public class CompositeFastListTest extends AbstractListTestCase { @Override protected <T> MutableList<T> newWith(T... littleElements) { CompositeFastList<T> result = new CompositeFastList<>(); for (T element : littleElements) { result.add(element); } return result; } @Override @Test public void testClone() { Verify.assertThrows(UnsupportedOperationException.class, () -> this.newWith().clone()); } @Test public void size() { CompositeFastList<String> list = new CompositeFastList<>(); Verify.assertSize(0, list); list.add("1"); Verify.assertSize(1, list); list.addAll(FastList.newListWith("1", "1", "1", "1")); Verify.assertSize(5, list); list.remove(1); Verify.assertSize(4, list); list.remove("1"); Verify.assertSize(3, list); list.add(3, "1"); Verify.assertSize(4, list); ListIterator<String> listIterator = list.listIterator(); listIterator.add("1"); Verify.assertSize(5, list); listIterator.next(); listIterator.remove(); Verify.assertSize(4, list); Iterator<String> iterator = list.iterator(); iterator.next(); iterator.remove(); Verify.assertSize(3, list); list.removeAll(FastList.newListWith("1")); Verify.assertSize(0, list); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("1", "2", "3", "4")); Verify.assertSize(8, list); list.clear(); Verify.assertSize(0, list); CompositeFastList<String> list2 = new CompositeFastList<>(); Verify.assertSize(0, list2); list2.listIterator().add("1"); Verify.assertSize(1, list2); } @Test public void testDefaultConstructor() { MutableList<String> list = new CompositeFastList<>(); list.add("1"); list.add("2"); Verify.assertSize(2, list); Verify.assertContains("1", list); } @Test public void parallelBatchForEach() { MutableList<Integer> integers = Interval.oneTo(1_000_000).toList().shuffleThis(); Collection<Integer> evens = ParallelIterate.select(integers, IntegerPredicates.isEven()); Verify.assertInstanceOf(CompositeFastList.class, evens); Collection<Integer> evens2 = ParallelIterate.select(evens, e -> e <= 100_000); Verify.assertInstanceOf(CompositeFastList.class, evens2); Verify.assertSize(50_000, evens2); Collection<String> evenStrings = ParallelIterate.collect(evens2, Object::toString); Verify.assertInstanceOf(CompositeFastList.class, evenStrings); Verify.assertSize(50_000, evenStrings); Assert.assertEquals(integers.select(e -> e <= 100_000).select(IntegerPredicates.isEven()).collect(Object::toString).toList(), evenStrings); Collection<Integer> odds = ParallelIterate.select(integers, IntegerPredicates.isOdd()); Verify.assertInstanceOf(CompositeFastList.class, odds); Collection<Integer> odds2 = ParallelIterate.select(odds, e -> e <= 100_000); Verify.assertInstanceOf(CompositeFastList.class, odds2); Verify.assertSize(50_000, odds2); Collection<String> oddStrings = ParallelIterate.collect(odds2, Object::toString); Verify.assertInstanceOf(CompositeFastList.class, oddStrings); Verify.assertSize(50_000, oddStrings); Assert.assertEquals(integers.select(e -> e <= 100_000).select(IntegerPredicates.isOdd()).collect(Object::toString).toList(), oddStrings); MutableList<Integer> range = Interval.fromTo(-1_234_567, 1_234_567).toList().shuffleThis(); Collection<Integer> positives = ParallelIterate.select(range, IntegerPredicates.isPositive()); Verify.assertInstanceOf(CompositeFastList.class, positives); Verify.assertSize(1_234_567, positives); Collection<Integer> evenPositives = ParallelIterate.select(positives, IntegerPredicates.isEven()); Verify.assertSize(617_283, evenPositives); Assert.assertEquals(2000, ParallelIterate.count(evenPositives, e -> e <= 4000)); Collection<Integer> oddPositives = ParallelIterate.select(positives, IntegerPredicates.isOdd()); Verify.assertSize(617_284, oddPositives); Assert.assertEquals(2000, ParallelIterate.count(oddPositives, e -> e <= 4000)); Collection<Integer> negatives = ParallelIterate.select(range, IntegerPredicates.isNegative()); Verify.assertInstanceOf(CompositeFastList.class, negatives); Verify.assertSize(1_234_567, negatives); Collection<Integer> evenNegatives = ParallelIterate.select(negatives, IntegerPredicates.isEven()); Verify.assertSize(617_283, evenNegatives); Assert.assertEquals(2000, ParallelIterate.count(evenNegatives, e -> e >= -4000)); Collection<Integer> oddNegatives = ParallelIterate.select(negatives, IntegerPredicates.isOdd()); Verify.assertSize(617_284, oddNegatives); Assert.assertEquals(2000, ParallelIterate.count(oddNegatives, e -> e >= -4000)); } @Test public void testGet() { MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("A", "B", "C", "B")); list.addAll(FastList.newListWith("Cat", "Dog", "Mouse", "Bird")); Assert.assertEquals("1", list.get(0)); Assert.assertEquals("2", list.get(1)); Assert.assertEquals("A", list.get(4)); Assert.assertEquals("4", list.get(3)); Assert.assertEquals("Cat", list.get(8)); Assert.assertEquals("Bird", list.get(11)); Verify.assertThrows(IndexOutOfBoundsException.class, () -> list.get(12)); } @Test public void testAddWithIndex() { MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("A", "B", "C", "B")); list.add(3, "NEW"); Verify.assertSize(9, list); Assert.assertEquals("NEW", list.get(3)); Assert.assertEquals("4", list.get(4)); list.add(0, "START"); Verify.assertSize(10, list); Assert.assertEquals("START", list.getFirst()); list.add(10, "END"); Verify.assertSize(11, list); Assert.assertEquals("END", list.getLast()); } @Override @Test public void reverseThis() { super.reverseThis(); CompositeFastList<Integer> composite = new CompositeFastList<>(); composite.addAll(FastList.newListWith(9, 8, 7)); composite.addAll(FastList.newListWith(6, 5, 4)); composite.addAll(FastList.newListWith(3, 2, 1)); CompositeFastList<Integer> reversed = composite.reverseThis(); Assert.assertSame(composite, reversed); Assert.assertEquals(Interval.oneTo(9), reversed); } @Override @Test public void addAllAtIndex() { Verify.assertThrows(UnsupportedOperationException.class, CompositeFastListTest.super::addAllAtIndex); } @Override @Test public void set() { super.set(); MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("A", "B", "C", "B")); Assert.assertEquals("1", list.set(0, "NEW")); Verify.assertSize(8, list); Assert.assertEquals("NEW", list.getFirst()); Assert.assertEquals("2", list.get(1)); Assert.assertEquals("B", list.set(7, "END")); Verify.assertSize(8, list); Assert.assertEquals("END", list.getLast()); } @Test public void set_bugFix_off_by_one_error() { CompositeFastList<Integer> compositeList = new CompositeFastList<>(); MutableList<Integer> list1 = FastList.newListWith(1, 2, 3); MutableList<Integer> list2 = FastList.newListWith(4, 5); MutableList<Integer> list3 = FastList.newList(); compositeList.addAll(list1); compositeList.addAll(list2); compositeList.addAll(list3); Assert.assertEquals(Integer.valueOf(4), compositeList.get(3)); Assert.assertEquals(Integer.valueOf(4), compositeList.set(3, 99)); Assert.assertEquals(Integer.valueOf(99), compositeList.get(3)); } @Override @Test public void indexOf() { super.indexOf(); MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("3", "B", "3", "B")); list.addAll(FastList.newListWith("3", "B", "3", "X")); Assert.assertEquals(2, list.indexOf("3")); Assert.assertEquals(5, list.indexOf("B")); Assert.assertEquals(11, list.indexOf("X")); Assert.assertEquals(-1, list.indexOf("missing")); } @Override @Test public void lastIndexOf() { super.lastIndexOf(); MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("3", "B", "3", "B")); Assert.assertEquals(6, list.lastIndexOf("3")); Assert.assertEquals(3, list.lastIndexOf("4")); Assert.assertEquals(-1, list.lastIndexOf("missing")); } @Test public void testRemoveWithIndex() { MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("3", "B", "3", "B")); Assert.assertEquals("1", list.remove(0)); Verify.assertSize(7, list); Assert.assertEquals("2", list.getFirst()); Assert.assertEquals("B", list.remove(6)); Verify.assertSize(6, list); Assert.assertEquals("3", list.getLast()); } @Override @Test public void toArray() { super.toArray(); MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(Lists.mutable.<String>of()); list.addAll(FastList.newListWith("3", "B", "3", "B")); list.addAll(Lists.mutable.<String>of()); Assert.assertArrayEquals(new String[]{"1", "2", "3", "4", "3", "B", "3", "B"}, list.toArray()); } @Test public void testEmptyIterator() { Assert.assertFalse(new CompositeFastList<String>().iterator().hasNext()); } @Override @Test public void clear() { super.clear(); MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("3", "B", "3", "B")); list.clear(); Assert.assertTrue(list.isEmpty()); Assert.assertEquals(0, list.size()); } @Test public void testContainsAll() { MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("3", "B", "3", "B")); Assert.assertTrue(list.containsAll(FastList.newList().with("2", "B"))); } @Override @Test public void removeAll() { super.removeAll(); MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("3", "B", "3", "B")); list.removeAll(FastList.newList().with("2", "B")); Verify.assertSize(5, list); } @Override @Test public void retainAll() { super.retainAll(); MutableList<String> list = new CompositeFastList<>(); list.addAll(FastList.newListWith("1", "2", "3", "4")); list.addAll(FastList.newListWith("3", "B", "3", "B")); list.retainAll(FastList.newList().with("2", "B")); Verify.assertSize(3, list); } @Override @Test public void forEach() { super.forEach(); MutableList<Integer> list = FastList.newList(); CompositeFastList<Integer> iterables = new CompositeFastList<>(); iterables.addComposited(Interval.oneTo(5).toList()); iterables.addComposited(Interval.fromTo(6, 10).toList()); iterables.forEach(CollectionAddProcedure.on(list)); Verify.assertSize(10, list); Verify.assertAllSatisfy(list, Predicates.greaterThan(0).and(Predicates.lessThan(11))); } @Override @Test public void forEachWithIndex() { super.forEachWithIndex(); MutableList<Integer> list = FastList.newList(); CompositeFastList<Integer> iterables = new CompositeFastList<>(); iterables.addComposited(Interval.fromTo(6, 10).toList()); iterables.addComposited(Interval.oneTo(5).toList()); iterables.forEachWithIndex((each, index) -> list.add(index, each)); Verify.assertSize(10, list); Verify.assertAllSatisfy(list, Predicates.greaterThan(0).and(Predicates.lessThan(11))); Verify.assertStartsWith(list, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5); } @Override @Test public void forEachWith() { super.forEachWith(); MutableList<Integer> list = FastList.newList(); CompositeFastList<Integer> iterables = new CompositeFastList<>(); iterables.addComposited(Interval.fromTo(6, 10).toList()); iterables.addComposited(Interval.oneTo(5).toList()); iterables.forEachWith((each, parameter) -> list.add(parameter.intValue(), each), 0); Verify.assertSize(10, list); Verify.assertAllSatisfy(list, Predicates.greaterThan(0).and(Predicates.lessThan(11))); Verify.assertStartsWith(list, 5, 4, 3, 2, 1, 10, 9, 8, 7, 6); } @Test public void testEquals() { CompositeFastList<String> composite = new CompositeFastList<>(); MutableList<String> list = FastList.newList(); Verify.assertEqualsAndHashCode(composite, list); MutableList<String> list2 = FastList.newListWith("one", "two", "three"); CompositeFastList<String> composite2 = new CompositeFastList<>(); MutableList<String> firstBit = FastList.newListWith("one", "two"); MutableList<String> secondBit = FastList.newListWith("three"); composite2.addAll(firstBit); composite2.addAll(secondBit); Verify.assertEqualsAndHashCode(list2, composite2); Assert.assertNotEquals(firstBit, composite2); Assert.assertNotEquals(composite2, firstBit); MutableList<String> list1 = FastList.newListWith("one", null, "three"); CompositeFastList<String> composite1 = new CompositeFastList<>(); MutableList<String> firstBit1 = FastList.newListWith("one", null); MutableList<String> secondBit1 = FastList.newListWith("three"); composite1.addAll(firstBit1); composite1.addAll(secondBit1); Verify.assertEqualsAndHashCode(list1, composite1); } @Test public void testHashCode() { CompositeFastList<String> composite = new CompositeFastList<>(); MutableList<String> list = FastList.newList(); Verify.assertEqualsAndHashCode(composite, list); MutableList<String> list2 = FastList.newListWith("one", "two", "three"); CompositeFastList<String> composite2 = new CompositeFastList<>(); MutableList<String> firstBit = FastList.newListWith("one", "two"); MutableList<String> secondBit = FastList.newListWith("three"); composite2.addAll(firstBit); composite2.addAll(secondBit); Verify.assertEqualsAndHashCode(list2, composite2); MutableList<String> list1 = FastList.newListWith("one", null, "three"); CompositeFastList<String> composite1 = new CompositeFastList<>(); MutableList<String> firstBit1 = FastList.newListWith("one", null); MutableList<String> secondBit1 = FastList.newListWith("three"); composite1.addAll(firstBit1); composite1.addAll(secondBit1); Verify.assertEqualsAndHashCode(list1, composite1); } @Override @Test public void listIterator() { super.listIterator(); CompositeFastList<String> composite = new CompositeFastList<>(); FastList<String> firstBit = FastList.newListWith("one", "two"); FastList<String> secondBit = FastList.newListWith("three"); composite.addAll(firstBit); composite.addAll(secondBit); ListIterator<String> listIterator = composite.listIterator(); listIterator.add("four"); Verify.assertSize(4, composite); Assert.assertTrue(listIterator.hasNext()); String element = listIterator.next(); Assert.assertEquals("one", element); String element3 = listIterator.next(); Assert.assertEquals("two", element3); String element2 = listIterator.previous(); Assert.assertEquals("two", element2); String element1 = listIterator.next(); Assert.assertEquals("two", element1); listIterator.remove(); Verify.assertSize(3, composite); } @Override @Test public void subList() { MutableList<String> list = this.newWith("A", "B", "C", "D"); MutableList<String> sublist = list.subList(1, 3); Verify.assertPostSerializedEqualsAndHashCode(sublist); Verify.assertSize(2, sublist); Verify.assertContainsAll(sublist, "B", "C"); sublist.add("X"); Verify.assertSize(3, sublist); Verify.assertContainsAll(sublist, "B", "C", "X"); Verify.assertSize(5, list); Verify.assertContainsAll(list, "A", "B", "C", "X", "D"); sublist.remove("X"); Verify.assertContainsAll(sublist, "B", "C"); Verify.assertContainsAll(list, "A", "B", "C", "D"); Assert.assertEquals("C", sublist.set(1, "R")); Verify.assertContainsAll(sublist, "B", "R"); Verify.assertContainsAll(list, "A", "B", "R", "D"); sublist.clear(); Verify.assertEmpty(sublist); Verify.assertContainsAll(list, "A", "D"); } @Test public void notRandomAccess() { Assert.assertFalse(this.newWith() instanceof RandomAccess); } @Test public void removingFromIteratorIsCool() { CompositeFastList<String> undertest = new CompositeFastList<>(); undertest.addAll(FastList.newListWith("a")); undertest.addAll(FastList.newListWith("b", "c", "d")); Iterator<String> iterator1 = undertest.iterator(); iterator1.next(); iterator1.next(); iterator1.next(); iterator1.remove(); Assert.assertEquals("d", iterator1.next()); Assert.assertEquals(FastList.newListWith("a", "b", "d"), undertest); Iterator<String> iterator2 = undertest.iterator(); iterator2.next(); iterator2.next(); iterator2.remove(); Assert.assertEquals(FastList.newListWith("a", "d"), undertest); Iterator<String> iterator3 = undertest.iterator(); iterator3.next(); iterator3.remove(); Assert.assertEquals(FastList.newListWith("d"), undertest); iterator3.next(); iterator3.remove(); Assert.assertEquals(FastList.newList(), undertest); } @Test(expected = IllegalStateException.class) public void removingFromIteratorIsUncoolFromEmptyIterator() { new CompositeFastList<String>().iterator().remove(); } }