/* * 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.utility; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.RandomAccess; import com.gs.collections.api.RichIterable; import com.gs.collections.api.block.HashingStrategy; import com.gs.collections.api.block.function.Function; import com.gs.collections.api.block.function.Function2; import com.gs.collections.api.block.function.Function3; import com.gs.collections.api.block.function.primitive.BooleanFunction; import com.gs.collections.api.block.function.primitive.ByteFunction; import com.gs.collections.api.block.function.primitive.CharFunction; import com.gs.collections.api.block.function.primitive.DoubleFunction; import com.gs.collections.api.block.function.primitive.DoubleObjectToDoubleFunction; import com.gs.collections.api.block.function.primitive.FloatFunction; import com.gs.collections.api.block.function.primitive.FloatObjectToFloatFunction; import com.gs.collections.api.block.function.primitive.IntFunction; import com.gs.collections.api.block.function.primitive.IntObjectToIntFunction; import com.gs.collections.api.block.function.primitive.LongFunction; import com.gs.collections.api.block.function.primitive.LongObjectToLongFunction; import com.gs.collections.api.block.function.primitive.ShortFunction; import com.gs.collections.api.block.predicate.Predicate; import com.gs.collections.api.block.predicate.Predicate2; import com.gs.collections.api.block.procedure.Procedure; import com.gs.collections.api.block.procedure.Procedure2; import com.gs.collections.api.block.procedure.primitive.ObjectIntProcedure; import com.gs.collections.api.collection.MutableCollection; import com.gs.collections.api.collection.primitive.MutableBooleanCollection; import com.gs.collections.api.collection.primitive.MutableByteCollection; import com.gs.collections.api.collection.primitive.MutableCharCollection; import com.gs.collections.api.collection.primitive.MutableDoubleCollection; import com.gs.collections.api.collection.primitive.MutableFloatCollection; import com.gs.collections.api.collection.primitive.MutableIntCollection; import com.gs.collections.api.collection.primitive.MutableLongCollection; import com.gs.collections.api.collection.primitive.MutableShortCollection; import com.gs.collections.api.list.ListIterable; import com.gs.collections.api.list.MutableList; import com.gs.collections.api.list.primitive.MutableBooleanList; import com.gs.collections.api.list.primitive.MutableByteList; import com.gs.collections.api.list.primitive.MutableCharList; import com.gs.collections.api.list.primitive.MutableDoubleList; import com.gs.collections.api.list.primitive.MutableFloatList; import com.gs.collections.api.list.primitive.MutableIntList; import com.gs.collections.api.list.primitive.MutableLongList; import com.gs.collections.api.list.primitive.MutableShortList; import com.gs.collections.api.map.MutableMap; import com.gs.collections.api.map.primitive.ObjectDoubleMap; import com.gs.collections.api.map.primitive.ObjectLongMap; import com.gs.collections.api.multimap.MutableMultimap; import com.gs.collections.api.partition.list.PartitionMutableList; import com.gs.collections.api.tuple.Pair; import com.gs.collections.api.tuple.Twin; import com.gs.collections.impl.block.factory.Comparators; import com.gs.collections.impl.block.factory.HashingStrategies; import com.gs.collections.impl.factory.Lists; import com.gs.collections.impl.list.mutable.FastList; import com.gs.collections.impl.multimap.list.FastListMultimap; import com.gs.collections.impl.partition.list.PartitionFastList; import com.gs.collections.impl.utility.internal.IterableIterate; import com.gs.collections.impl.utility.internal.RandomAccessListIterate; /** * The ListIterate utility class can be useful for iterating over lists, especially if there * is a desire to return a MutableList from any of the iteration methods. * * @since 1.0 */ public final class ListIterate { private ListIterate() { throw new AssertionError("Suppress default constructor for noninstantiability"); } public static boolean equals(List<?> one, List<?> two) { if (one.size() != two.size()) // we assume that size() is a constant time operation in most lists { return false; } if (one instanceof RandomAccess) { return two instanceof RandomAccess ? ListIterate.randomAccessEquals(one, two) : ListIterate.oneRandomAccessEquals(one, two); } return two instanceof RandomAccess ? ListIterate.oneRandomAccessEquals(two, one) : ListIterate.nonRandomAccessEquals(one, two); } private static boolean randomAccessEquals(List<?> one, List<?> two) { int localSize = one.size(); for (int i = 0; i < localSize; i++) { if (!Comparators.nullSafeEquals(one.get(i), two.get(i))) { return false; } } return true; } private static boolean oneRandomAccessEquals(List<?> one, List<?> two) { int localSize = one.size(); Iterator<?> twoIterator = two.iterator(); for (int i = 0; i < localSize; i++) { if (!twoIterator.hasNext() || !Comparators.nullSafeEquals(one.get(i), twoIterator.next())) { return false; } } return !twoIterator.hasNext(); } private static boolean nonRandomAccessEquals(List<?> one, List<?> two) { Iterator<?> oneIterator = one.iterator(); Iterator<?> twoIterator = two.iterator(); while (oneIterator.hasNext()) { if (!twoIterator.hasNext() || !Comparators.nullSafeEquals(oneIterator.next(), twoIterator.next())) { return false; } } return !twoIterator.hasNext(); } public static <T> void toArray(List<T> list, T[] target, int startIndex, int sourceSize) { if (list instanceof RandomAccess) { RandomAccessListIterate.toArray(list, target, startIndex, sourceSize); } else { int index = 0; ListIterator<T> iterator = list.listIterator(); while (iterator.hasNext() && index < sourceSize) { target[startIndex + index] = iterator.next(); index++; } } } /** * @see Iterate#select(Iterable, Predicate) */ public static <T> MutableList<T> select(List<T> list, Predicate<? super T> predicate) { return ListIterate.select(list, predicate, FastList.<T>newList()); } /** * @see Iterate#selectWith(Iterable, Predicate2, Object) */ public static <T, IV> MutableList<T> selectWith( List<T> list, Predicate2<? super T, ? super IV> predicate, IV injectedValue) { return ListIterate.selectWith(list, predicate, injectedValue, FastList.<T>newList()); } /** * @see Iterate#select(Iterable, Predicate, Collection) */ public static <T, R extends Collection<T>> R select( List<T> list, Predicate<? super T> predicate, R targetCollection) { if (list instanceof RandomAccess) { return RandomAccessListIterate.select(list, predicate, targetCollection); } return IterableIterate.select(list, predicate, targetCollection); } /** * @see Iterate#selectWith(Iterable, Predicate2, Object, Collection) */ public static <T, P, R extends Collection<T>> R selectWith( List<T> list, Predicate2<? super T, ? super P> predicate, P parameter, R targetCollection) { if (list instanceof RandomAccess) { return RandomAccessListIterate.selectWith(list, predicate, parameter, targetCollection); } return IterableIterate.selectWith(list, predicate, parameter, targetCollection); } /** * @see Iterate#selectInstancesOf(Iterable, Class) */ public static <T, S> MutableList<S> selectInstancesOf( List<T> list, Class<S> clazz) { if (list instanceof RandomAccess) { return RandomAccessListIterate.selectInstancesOf(list, clazz); } return IterableIterate.selectInstancesOf(list, clazz); } /** * @see Iterate#count(Iterable, Predicate) */ public static <T> int count(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.count(list, predicate); } return IterableIterate.count(list, predicate); } /** * @see Iterate#countWith(Iterable, Predicate2, Object) */ public static <T, IV> int countWith( List<T> list, Predicate2<? super T, ? super IV> predicate, IV injectedValue) { if (list instanceof RandomAccess) { return RandomAccessListIterate.countWith(list, predicate, injectedValue); } return IterableIterate.countWith(list, predicate, injectedValue); } /** * @see Iterate#collectIf(Iterable, Predicate, Function) */ public static <T, A> MutableList<A> collectIf( List<T> list, Predicate<? super T> predicate, Function<? super T, ? extends A> function) { return ListIterate.collectIf(list, predicate, function, FastList.<A>newList()); } /** * @see Iterate#collectIf(Iterable, Predicate, Function, Collection) */ public static <T, A, R extends Collection<A>> R collectIf( List<T> list, Predicate<? super T> predicate, Function<? super T, ? extends A> function, R targetCollection) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectIf(list, predicate, function, targetCollection); } return IterableIterate.collectIf(list, predicate, function, targetCollection); } /** * @see Iterate#reject(Iterable, Predicate) */ public static <T> MutableList<T> reject(List<T> list, Predicate<? super T> predicate) { return ListIterate.reject(list, predicate, FastList.<T>newList()); } /** * @see Iterate#rejectWith(Iterable, Predicate2, Object) */ public static <T, IV> MutableList<T> rejectWith( List<T> list, Predicate2<? super T, ? super IV> predicate, IV injectedValue) { return ListIterate.rejectWith(list, predicate, injectedValue, FastList.<T>newList()); } /** * @see Iterate#reject(Iterable, Predicate, Collection) */ public static <T, R extends Collection<T>> R reject( List<T> list, Predicate<? super T> predicate, R targetCollection) { if (list instanceof RandomAccess) { return RandomAccessListIterate.reject(list, predicate, targetCollection); } return IterableIterate.reject(list, predicate, targetCollection); } /** * @see Iterate#reject(Iterable, Predicate, Collection) */ public static <T, P, R extends Collection<T>> R rejectWith( List<T> list, Predicate2<? super T, ? super P> predicate, P parameter, R targetCollection) { if (list instanceof RandomAccess) { return RandomAccessListIterate.rejectWith(list, predicate, parameter, targetCollection); } return IterableIterate.rejectWith(list, predicate, parameter, targetCollection); } /** * @see Iterate#collect(Iterable, Function) */ public static <T, A> MutableList<A> collect( List<T> list, Function<? super T, ? extends A> function) { return ListIterate.collect(list, function, FastList.<A>newList(list.size())); } /** * @see Iterate#collect(Iterable, Function, Collection) */ public static <T, A, R extends Collection<A>> R collect( List<T> list, Function<? super T, ? extends A> function, R targetCollection) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collect(list, function, targetCollection); } return IterableIterate.collect(list, function, targetCollection); } /** * @see Iterate#collectBoolean(Iterable, BooleanFunction) */ public static <T> MutableBooleanList collectBoolean( List<T> list, BooleanFunction<? super T> booleanFunction) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectBoolean(list, booleanFunction); } return (MutableBooleanList) IterableIterate.collectBoolean(list, booleanFunction); } /** * @see Iterate#collectBoolean(Iterable, BooleanFunction, MutableBooleanCollection) */ public static <T, R extends MutableBooleanCollection> R collectBoolean( List<T> list, BooleanFunction<? super T> booleanFunction, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectBoolean(list, booleanFunction, target); } return IterableIterate.collectBoolean(list, booleanFunction, target); } /** * @see Iterate#collectByte(Iterable, ByteFunction) */ public static <T> MutableByteList collectByte( List<T> list, ByteFunction<? super T> byteFunction) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectByte(list, byteFunction); } return (MutableByteList) IterableIterate.collectByte(list, byteFunction); } /** * @see Iterate#collectByte(Iterable, ByteFunction, MutableByteCollection) */ public static <T, R extends MutableByteCollection> R collectByte( List<T> list, ByteFunction<? super T> byteFunction, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectByte(list, byteFunction, target); } return IterableIterate.collectByte(list, byteFunction, target); } /** * @see Iterate#collectChar(Iterable, CharFunction) */ public static <T> MutableCharList collectChar( List<T> list, CharFunction<? super T> charFunction) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectChar(list, charFunction); } return (MutableCharList) IterableIterate.collectChar(list, charFunction); } /** * @see Iterate#collectChar(Iterable, CharFunction, MutableCharCollection) */ public static <T, R extends MutableCharCollection> R collectChar( List<T> list, CharFunction<? super T> charFunction, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectChar(list, charFunction, target); } return IterableIterate.collectChar(list, charFunction, target); } /** * @see Iterate#collectDouble(Iterable, DoubleFunction) */ public static <T> MutableDoubleList collectDouble( List<T> list, DoubleFunction<? super T> doubleFunction) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectDouble(list, doubleFunction); } return (MutableDoubleList) IterableIterate.collectDouble(list, doubleFunction); } /** * @see Iterate#collectDouble(Iterable, DoubleFunction, MutableDoubleCollection) */ public static <T, R extends MutableDoubleCollection> R collectDouble( List<T> list, DoubleFunction<? super T> doubleFunction, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectDouble(list, doubleFunction, target); } return IterableIterate.collectDouble(list, doubleFunction, target); } /** * @see Iterate#collectFloat(Iterable, FloatFunction) */ public static <T> MutableFloatList collectFloat( List<T> list, FloatFunction<? super T> floatFunction) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectFloat(list, floatFunction); } return (MutableFloatList) IterableIterate.collectFloat(list, floatFunction); } /** * @see Iterate#collectFloat(Iterable, FloatFunction, MutableFloatCollection) */ public static <T, R extends MutableFloatCollection> R collectFloat( List<T> list, FloatFunction<? super T> floatFunction, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectFloat(list, floatFunction, target); } return IterableIterate.collectFloat(list, floatFunction, target); } /** * @see Iterate#collectInt(Iterable, IntFunction) */ public static <T> MutableIntList collectInt( List<T> list, IntFunction<? super T> intFunction) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectInt(list, intFunction); } return (MutableIntList) IterableIterate.collectInt(list, intFunction); } /** * @see Iterate#collectInt(Iterable, IntFunction, MutableIntCollection) */ public static <T, R extends MutableIntCollection> R collectInt( List<T> list, IntFunction<? super T> intFunction, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectInt(list, intFunction, target); } return IterableIterate.collectInt(list, intFunction, target); } /** * @see Iterate#collectLong(Iterable, LongFunction) */ public static <T> MutableLongList collectLong( List<T> list, LongFunction<? super T> longFunction) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectLong(list, longFunction); } return (MutableLongList) IterableIterate.collectLong(list, longFunction); } /** * @see Iterate#collectLong(Iterable, LongFunction, MutableLongCollection) */ public static <T, R extends MutableLongCollection> R collectLong( List<T> list, LongFunction<? super T> longFunction, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectLong(list, longFunction, target); } return IterableIterate.collectLong(list, longFunction, target); } /** * @see Iterate#collectShort(Iterable, ShortFunction) */ public static <T> MutableShortList collectShort( List<T> list, ShortFunction<? super T> shortFunction) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectShort(list, shortFunction); } return (MutableShortList) IterableIterate.collectShort(list, shortFunction); } /** * @see Iterate#collectShort(Iterable, ShortFunction, MutableShortCollection) */ public static <T, R extends MutableShortCollection> R collectShort( List<T> list, ShortFunction<? super T> shortFunction, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectShort(list, shortFunction, target); } return IterableIterate.collectShort(list, shortFunction, target); } /** * @see Iterate#flatCollect(Iterable, Function) */ public static <T, A> MutableList<A> flatCollect( List<T> list, Function<? super T, ? extends Iterable<A>> function) { return ListIterate.flatCollect(list, function, FastList.<A>newList(list.size())); } /** * @see Iterate#flatCollect(Iterable, Function, Collection) */ public static <T, A, R extends Collection<A>> R flatCollect( List<T> list, Function<? super T, ? extends Iterable<A>> function, R targetCollection) { if (list instanceof RandomAccess) { return RandomAccessListIterate.flatCollect(list, function, targetCollection); } return IterableIterate.flatCollect(list, function, targetCollection); } /** * Returns the first element of a list. */ public static <T> T getFirst(List<T> collection) { return Iterate.isEmpty(collection) ? null : collection.get(0); } /** * Returns the last element of a list. */ public static <T> T getLast(List<T> list) { if (list == null) { return null; } if (list instanceof RandomAccess) { return RandomAccessListIterate.getLast(list); } ListIterator<T> iterator = list.listIterator(list.size()); if (iterator.hasPrevious()) { return iterator.previous(); } return null; } /** * @see Iterate#forEach(Iterable, Procedure) */ public static <T> void forEach(List<T> list, Procedure<? super T> procedure) { if (list instanceof RandomAccess) { RandomAccessListIterate.forEach(list, procedure); } else { IterableIterate.forEach(list, procedure); } } /** * Iterates over the List in reverse order executing the Procedure for each element */ public static <T> void reverseForEach(List<T> list, Procedure<? super T> procedure) { if (!list.isEmpty()) { ListIterate.forEach(list, list.size() - 1, 0, procedure); } } /** * Iterates over the List in reverse order executing the Procedure for each element. The index passed into the ObjectIntProcedure is the actual index of the * range. */ public static <T> void reverseForEachWithIndex(List<T> list, ObjectIntProcedure<? super T> objectIntProcedure) { if (!list.isEmpty()) { ListIterate.forEachWithIndex(list, list.size() - 1, 0, objectIntProcedure); } } /** * Iterates over the section of the list covered by the specified indexes. The indexes are both inclusive. If the * from is less than the to, the list is iterated in forward order. If the from is greater than the to, then the * list is iterated in the reverse order. * <p> * <pre>e.g. * MutableList<People> people = FastList.newListWith(ted, mary, bob, sally); * ListIterate.forEach(people, 0, 1, new Procedure<Person>() * { * public void value(Person person) * { * LOGGER.info(person.getName()); * } * }); * </pre> * <p> * This code would output ted and mary's names. */ public static <T> void forEach(List<T> list, int from, int to, Procedure<? super T> procedure) { ListIterate.rangeCheck(from, to, list.size()); if (list instanceof RandomAccess) { RandomAccessListIterate.forEach(list, from, to, procedure); } else { if (from <= to) { ListIterator<T> iterator = list.listIterator(from); for (int i = from; i <= to; i++) { procedure.value(iterator.next()); } } else { ListIterator<T> iterator = list.listIterator(from + 1); for (int i = from; i >= to; i--) { procedure.value(iterator.previous()); } } } } /** * Iterates over the section of the list covered by the specified indexes. The indexes are both inclusive. If the * from is less than the to, the list is iterated in forward order. If the from is greater than the to, then the * list is iterated in the reverse order. The index passed into the ObjectIntProcedure is the actual index of the * range. * <p> * <pre>e.g. * MutableList<People> people = FastList.newListWith(ted, mary, bob, sally); * ListIterate.forEachWithIndex(people, 0, 1, new ObjectIntProcedure<Person>() * { * public void value(Person person, int index) * { * LOGGER.info(person.getName() + " at index: " + index); * } * }); * </pre> * <p> * This code would output ted and mary's names. */ public static <T> void forEachWithIndex(List<T> list, int from, int to, ObjectIntProcedure<? super T> objectIntProcedure) { ListIterate.rangeCheck(from, to, list.size()); if (list instanceof RandomAccess) { RandomAccessListIterate.forEachWithIndex(list, from, to, objectIntProcedure); } else { if (from <= to) { ListIterator<T> iterator = list.listIterator(from); for (int i = from; i <= to; i++) { objectIntProcedure.value(iterator.next(), i); } } else { ListIterator<T> iterator = list.listIterator(from + 1); for (int i = from; i >= to; i--) { objectIntProcedure.value(iterator.previous(), i); } } } } public static void rangeCheck(int from, int to, int size) { if (from < 0) { throw new IndexOutOfBoundsException("From index: " + from); } if (to < 0) { throw new IndexOutOfBoundsException("To index: " + to); } if (from >= size) { throw new IndexOutOfBoundsException("From index: " + from + " Size: " + size); } if (to >= size) { throw new IndexOutOfBoundsException("To index: " + to + " Size: " + size); } } /** * Iterates over both lists together, evaluating Procedure2 with the current element from each list. */ public static <T1, T2> void forEachInBoth(List<T1> list1, List<T2> list2, Procedure2<? super T1, ? super T2> procedure) { if (list1 != null && list2 != null) { if (list1.size() == list2.size()) { if (list1 instanceof RandomAccess && list2 instanceof RandomAccess) { RandomAccessListIterate.forEachInBoth(list1, list2, procedure); } else { Iterator<T1> iterator1 = list1.iterator(); Iterator<T2> iterator2 = list2.iterator(); int size = list2.size(); for (int i = 0; i < size; i++) { procedure.value(iterator1.next(), iterator2.next()); } } } else { throw new RuntimeException("Attempt to call forEachInBoth with two Lists of different sizes :" + list1.size() + ':' + list2.size()); } } } /** * @see Iterate#forEachWithIndex(Iterable, ObjectIntProcedure) */ public static <T> void forEachWithIndex(List<T> list, ObjectIntProcedure<? super T> objectIntProcedure) { if (list instanceof RandomAccess) { RandomAccessListIterate.forEachWithIndex(list, objectIntProcedure); } else { IterableIterate.forEachWithIndex(list, objectIntProcedure); } } /** * @see Iterate#detect(Iterable, Predicate) */ public static <T> T detect(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.detect(list, predicate); } return IterableIterate.detect(list, predicate); } /** * @see Iterate#detectWith(Iterable, Predicate2, Object) */ public static <T, IV> T detectWith( List<T> list, Predicate2<? super T, ? super IV> predicate, IV injectedValue) { if (list instanceof RandomAccess) { return RandomAccessListIterate.detectWith(list, predicate, injectedValue); } return IterableIterate.detectWith(list, predicate, injectedValue); } /** * @see Iterate#detectIfNone(Iterable, Predicate, Object) */ public static <T> T detectIfNone(List<T> list, Predicate<? super T> predicate, T ifNone) { T result = ListIterate.detect(list, predicate); return result == null ? ifNone : result; } /** * @see Iterate#detectWithIfNone(Iterable, Predicate2, Object, Object) */ public static <T, IV> T detectWithIfNone(List<T> list, Predicate2<? super T, ? super IV> predicate, IV injectedValue, T ifNone) { T result = ListIterate.detectWith(list, predicate, injectedValue); return result == null ? ifNone : result; } /** * @see Iterate#injectInto(Object, Iterable, Function2) */ public static <T, IV> IV injectInto(IV injectValue, List<T> list, Function2<? super IV, ? super T, ? extends IV> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.injectInto(injectValue, list, function); } return IterableIterate.injectInto(injectValue, list, function); } /** * @see Iterate#injectInto(int, Iterable, IntObjectToIntFunction) */ public static <T> int injectInto(int injectValue, List<T> list, IntObjectToIntFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.injectInto(injectValue, list, function); } return IterableIterate.injectInto(injectValue, list, function); } /** * @see Iterate#injectInto(long, Iterable, LongObjectToLongFunction) */ public static <T> long injectInto(long injectValue, List<T> list, LongObjectToLongFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.injectInto(injectValue, list, function); } return IterableIterate.injectInto(injectValue, list, function); } /** * @see Iterate#injectInto(double, Iterable, DoubleObjectToDoubleFunction) */ public static <T> double injectInto(double injectValue, List<T> list, DoubleObjectToDoubleFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.injectInto(injectValue, list, function); } return IterableIterate.injectInto(injectValue, list, function); } /** * @see Iterate#injectInto(float, Iterable, FloatObjectToFloatFunction) */ public static <T> float injectInto(float injectValue, List<T> list, FloatObjectToFloatFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.injectInto(injectValue, list, function); } return IterableIterate.injectInto(injectValue, list, function); } public static <T> long sumOfInt(List<T> list, IntFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumOfInt(list, function); } return IterableIterate.sumOfInt(list, function); } public static <T> long sumOfLong(List<T> list, LongFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumOfLong(list, function); } return IterableIterate.sumOfLong(list, function); } public static <T> double sumOfFloat(List<T> list, FloatFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumOfFloat(list, function); } return IterableIterate.sumOfFloat(list, function); } public static <T> double sumOfDouble(List<T> list, DoubleFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumOfDouble(list, function); } return IterableIterate.sumOfDouble(list, function); } public static <T> BigDecimal sumOfBigDecimal(List<T> list, Function<? super T, BigDecimal> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumOfBigDecimal(list, function); } return IterableIterate.sumOfBigDecimal(list, function); } public static <T> BigInteger sumOfBigInteger(List<T> list, Function<? super T, BigInteger> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumOfBigInteger(list, function); } return IterableIterate.sumOfBigInteger(list, function); } public static <V, T> MutableMap<V, BigDecimal> sumByBigDecimal(List<T> list, Function<T, V> groupBy, Function<? super T, BigDecimal> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumByBigDecimal(list, groupBy, function); } return IterableIterate.sumByBigDecimal(list, groupBy, function); } public static <V, T> MutableMap<V, BigInteger> sumByBigInteger(List<T> list, Function<T, V> groupBy, Function<? super T, BigInteger> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumByBigInteger(list, groupBy, function); } return IterableIterate.sumByBigInteger(list, groupBy, function); } public static <V, T> ObjectLongMap<V> sumByInt(List<T> list, Function<T, V> groupBy, IntFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumByInt(list, groupBy, function); } return IterableIterate.sumByInt(list, groupBy, function); } public static <V, T> ObjectLongMap<V> sumByLong(List<T> list, Function<T, V> groupBy, LongFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumByLong(list, groupBy, function); } return IterableIterate.sumByLong(list, groupBy, function); } public static <V, T> ObjectDoubleMap<V> sumByFloat(List<T> list, Function<T, V> groupBy, FloatFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumByFloat(list, groupBy, function); } return IterableIterate.sumByFloat(list, groupBy, function); } public static <V, T> ObjectDoubleMap<V> sumByDouble(List<T> list, Function<T, V> groupBy, DoubleFunction<? super T> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.sumByDouble(list, groupBy, function); } return IterableIterate.sumByDouble(list, groupBy, function); } /** * @see Iterate#anySatisfy(Iterable, Predicate) */ public static <T> boolean anySatisfy(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.anySatisfy(list, predicate); } return IterableIterate.anySatisfy(list, predicate); } /** * @see Iterate#anySatisfyWith(Iterable, Predicate2, Object) */ public static <T, IV> boolean anySatisfyWith(List<T> list, Predicate2<? super T, ? super IV> predicate, IV injectedValue) { if (list instanceof RandomAccess) { return RandomAccessListIterate.anySatisfyWith(list, predicate, injectedValue); } return IterableIterate.anySatisfyWith(list, predicate, injectedValue); } /** * @see Iterate#allSatisfy(Iterable, Predicate) */ public static <T> boolean allSatisfy(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.allSatisfy(list, predicate); } return IterableIterate.allSatisfy(list, predicate); } /** * @see Iterate#allSatisfyWith(Iterable, Predicate2, Object) */ public static <T, IV> boolean allSatisfyWith(List<T> list, Predicate2<? super T, ? super IV> predicate, IV injectedValue) { if (list instanceof RandomAccess) { return RandomAccessListIterate.allSatisfyWith(list, predicate, injectedValue); } return IterableIterate.allSatisfyWith(list, predicate, injectedValue); } /** * @see Iterate#noneSatisfy(Iterable, Predicate) */ public static <T> boolean noneSatisfy(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.noneSatisfy(list, predicate); } return IterableIterate.noneSatisfy(list, predicate); } /** * @see Iterate#noneSatisfyWith(Iterable, Predicate2, Object) */ public static <T, P> boolean noneSatisfyWith(List<T> list, Predicate2<? super T, ? super P> predicate, P injectedValue) { if (list instanceof RandomAccess) { return RandomAccessListIterate.noneSatisfyWith(list, predicate, injectedValue); } return IterableIterate.noneSatisfyWith(list, predicate, injectedValue); } /** * @see Iterate#selectAndRejectWith(Iterable, Predicate2, Object) */ public static <T, IV> Twin<MutableList<T>> selectAndRejectWith( List<T> list, Predicate2<? super T, ? super IV> predicate, IV injectedValue) { if (list instanceof RandomAccess) { return RandomAccessListIterate.selectAndRejectWith(list, predicate, injectedValue); } return IterableIterate.selectAndRejectWith(list, predicate, injectedValue); } /** * @see Iterate#partition(Iterable, Predicate) */ public static <T> PartitionMutableList<T> partition(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.partition(list, predicate); } return IterableIterate.partition(list, predicate); } public static <T, P> PartitionMutableList<T> partitionWith(List<T> list, Predicate2<? super T, ? super P> predicate, P parameter) { if (list instanceof RandomAccess) { return RandomAccessListIterate.partitionWith(list, predicate, parameter); } return IterableIterate.partitionWith(list, predicate, parameter); } /** * @see Iterate#removeIf(Iterable, Predicate) */ public static <T> boolean removeIf(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.removeIf(list, predicate); } return IterableIterate.removeIf(list, predicate); } /** * @see Iterate#removeIfWith(Iterable, Predicate2, Object) */ public static <T, P> boolean removeIfWith(List<T> list, Predicate2<? super T, ? super P> predicate, P parameter) { if (list instanceof RandomAccess) { return RandomAccessListIterate.removeIfWith(list, predicate, parameter); } return IterableIterate.removeIfWith(list, predicate, parameter); } public static <T> boolean removeIf(List<T> list, Predicate<? super T> predicate, Procedure<? super T> procedure) { if (list instanceof RandomAccess) { return RandomAccessListIterate.removeIf(list, predicate, procedure); } return IterableIterate.removeIf(list, predicate, procedure); } public static <T, P> boolean removeIfWith(List<T> list, Predicate2<? super T, ? super P> predicate, P parameter, Procedure<? super T> procedure) { if (list instanceof RandomAccess) { return RandomAccessListIterate.removeIfWith(list, predicate, parameter, procedure); } return IterableIterate.removeIfWith(list, predicate, parameter, procedure); } /** * Searches for the first index where the predicate evaluates to true. */ public static <T> int detectIndex(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.detectIndex(list, predicate); } return IterableIterate.detectIndex(list, predicate); } /** * Searches for the first index where the predicate2 and parameter evaluates to true. */ public static <T, P> int detectIndexWith(List<T> list, Predicate2<? super T, ? super P> predicate, P parameter) { if (list instanceof RandomAccess) { return RandomAccessListIterate.detectIndexWith(list, predicate, parameter); } return IterableIterate.detectIndexWith(list, predicate, parameter); } /** * Returns the last index where the predicate evaluates to true. * Returns -1 for no matches. */ public static <T> int detectLastIndex(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.detectLastIndex(list, predicate); } int size = list.size(); int i = size - 1; ListIterator<T> reverseIterator = list.listIterator(size); while (reverseIterator.hasPrevious()) { if (predicate.accept(reverseIterator.previous())) { return i; } i--; } return -1; } public static <T, IV, P> IV injectIntoWith(IV injectedValue, List<T> list, Function3<? super IV, ? super T, ? super P, ? extends IV> function, P parameter) { if (list instanceof RandomAccess) { return RandomAccessListIterate.injectIntoWith(injectedValue, list, function, parameter); } return IterableIterate.injectIntoWith(injectedValue, list, function, parameter); } /** * @see Iterate#forEachWith(Iterable, Procedure2, Object) */ public static <T, P> void forEachWith(List<T> list, Procedure2<? super T, ? super P> procedure, P parameter) { if (list instanceof RandomAccess) { RandomAccessListIterate.forEachWith(list, procedure, parameter); } else { IterableIterate.forEachWith(list, procedure, parameter); } } /** * @see Iterate#collectWith(Iterable, Function2, Object) */ public static <T, P, A> MutableList<A> collectWith( List<T> list, Function2<? super T, ? super P, ? extends A> function, P parameter) { return ListIterate.collectWith(list, function, parameter, FastList.<A>newList(list.size())); } /** * @see Iterate#collectWith(Iterable, Function2, Object, Collection) */ public static <T, P, A, R extends Collection<A>> R collectWith( List<T> list, Function2<? super T, ? super P, ? extends A> function, P parameter, R targetCollection) { if (list instanceof RandomAccess) { return RandomAccessListIterate.collectWith(list, function, parameter, targetCollection); } return IterableIterate.collectWith(list, function, parameter, targetCollection); } /** * @deprecated in 7.0. */ @Deprecated public static <T, R extends List<T>> R distinct(List<T> list, R targetList) { if (list instanceof RandomAccess) { return RandomAccessListIterate.distinct(list, targetList); } return IterableIterate.distinct(list, targetList); } /** * @since 7.0. */ public static <T> MutableList<T> distinct(List<T> list) { return ListIterate.distinct(list, FastList.<T>newList()); } /** * @since 7.0. */ public static <T> MutableList<T> distinct(List<T> list, HashingStrategy<? super T> hashingStrategy) { if (list instanceof RandomAccess) { return RandomAccessListIterate.distinct(list, hashingStrategy); } return IterableIterate.distinct(list, hashingStrategy); } /** * Reverses the order of the items in the list. * <pre> * List<Integer> integers = Lists.fixedSize.of(1, 3, 2); * Verify.assertListsEqual(FastList.newListWith(2, 3, 1), ListIterate.reverse(integers)); * </pre> * * @return the reversed list */ public static <T> List<T> reverseThis(List<T> list) { Collections.reverse(list); return list; } /** * @see Iterate#take(Iterable, int) */ public static <T> MutableList<T> take(List<T> list, int count) { if (count < 0) { throw new IllegalArgumentException("Count must be greater than zero, but was: " + count); } if (list instanceof RandomAccess) { return RandomAccessListIterate.take(list, count, FastList.<T>newList(Math.min(list.size(), count))); } return ListIterate.take(list, count, FastList.<T>newList()); } /** * @see Iterate#take(Iterable, int) */ public static <T, R extends Collection<T>> R take(List<T> list, int count, R targetList) { if (count < 0) { throw new IllegalArgumentException("Count must be greater than zero, but was: " + count); } if (list instanceof RandomAccess) { return RandomAccessListIterate.take(list, count, targetList); } return IterableIterate.take(list, count, targetList); } /** * @see Iterate#drop(Iterable, int) */ public static <T> MutableList<T> drop(List<T> list, int count) { if (count < 0) { throw new IllegalArgumentException("Count must be greater than zero, but was: " + count); } if (list instanceof RandomAccess) { return RandomAccessListIterate.drop(list, count, FastList.<T>newList(list.size() - Math.min(list.size(), count))); } return ListIterate.drop(list, count, FastList.<T>newList()); } /** * @see Iterate#drop(Iterable, int) */ public static <T, R extends Collection<T>> R drop(List<T> list, int count, R targetList) { if (count < 0) { throw new IllegalArgumentException("Count must be greater than zero, but was: " + count); } if (list instanceof RandomAccess) { return RandomAccessListIterate.drop(list, count, targetList); } return IterableIterate.drop(list, count, targetList); } /** * @see RichIterable#appendString(Appendable, String, String, String) */ public static <T> void appendString( List<T> list, Appendable appendable, String start, String separator, String end) { if (list instanceof RandomAccess) { RandomAccessListIterate.appendString(list, appendable, start, separator, end); } else { IterableIterate.appendString(list, appendable, start, separator, end); } } /** * @see Iterate#groupBy(Iterable, Function) */ public static <T, V> FastListMultimap<V, T> groupBy( List<T> list, Function<? super T, ? extends V> function) { return ListIterate.groupBy(list, function, FastListMultimap.<V, T>newMultimap()); } /** * @see Iterate#groupBy(Iterable, Function, MutableMultimap) */ public static <T, V, R extends MutableMultimap<V, T>> R groupBy( List<T> list, Function<? super T, ? extends V> function, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.groupBy(list, function, target); } return IterableIterate.groupBy(list, function, target); } /** * @see Iterate#groupByEach(Iterable, Function) */ public static <T, V> FastListMultimap<V, T> groupByEach( List<T> list, Function<? super T, ? extends Iterable<V>> function) { return ListIterate.groupByEach(list, function, FastListMultimap.<V, T>newMultimap()); } /** * @see Iterate#groupByEach(Iterable, Function, MutableMultimap) */ public static <T, V, R extends MutableMultimap<V, T>> R groupByEach( List<T> list, Function<? super T, ? extends Iterable<V>> function, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.groupByEach(list, function, target); } return IterableIterate.groupByEach(list, function, target); } /** * @see Iterate#groupByUniqueKey(Iterable, Function) */ public static <K, T> MutableMap<K, T> groupByUniqueKey( List<T> list, Function<? super T, ? extends K> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.groupByUniqueKey(list, function); } return IterableIterate.groupByUniqueKey(list, function); } /** * @see Iterate#groupByUniqueKey(Iterable, Function, MutableMap) */ public static <K, T, R extends MutableMap<K, T>> R groupByUniqueKey( List<T> list, Function<? super T, ? extends K> function, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.groupByUniqueKey(list, function, target); } return IterableIterate.groupByUniqueKey(list, function, target); } /** * @see Iterate#min(Iterable, Comparator) */ public static <T> T min(List<T> list, Comparator<? super T> comparator) { if (list instanceof RandomAccess) { return RandomAccessListIterate.min(list, comparator); } return IterableIterate.min(list, comparator); } public static <T, V extends Comparable<? super V>> T minBy(List<T> list, Function<? super T, ? extends V> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.minBy(list, function); } return IterableIterate.minBy(list, function); } public static <T, V extends Comparable<? super V>> T maxBy(List<T> list, Function<? super T, ? extends V> function) { if (list instanceof RandomAccess) { return RandomAccessListIterate.maxBy(list, function); } return IterableIterate.maxBy(list, function); } /** * @see Iterate#max(Iterable, Comparator) */ public static <T> T max(List<T> list, Comparator<? super T> comparator) { if (list instanceof RandomAccess) { return RandomAccessListIterate.max(list, comparator); } return IterableIterate.max(list, comparator); } /** * @see Iterate#min(Iterable) */ public static <T> T min(List<T> list) { if (list instanceof RandomAccess) { return RandomAccessListIterate.min(list); } return IterableIterate.min(list); } /** * @see Iterate#max(Iterable) */ public static <T> T max(List<T> list) { if (list instanceof RandomAccess) { return RandomAccessListIterate.max(list); } return IterableIterate.max(list); } /** * @see Iterate#chunk(Iterable, int) */ public static <T> RichIterable<RichIterable<T>> chunk(List<T> list, int size) { if (size <= 0) { throw new IllegalArgumentException("Size for groups must be positive but was: " + size); } Iterator<T> iterator = list.iterator(); MutableList<RichIterable<T>> result = Lists.mutable.empty(); while (iterator.hasNext()) { MutableCollection<T> batch = Lists.mutable.empty(); for (int i = 0; i < size && iterator.hasNext(); i++) { batch.add(iterator.next()); } result.add(batch); } return result; } /** * @see Iterate#zip(Iterable, Iterable) */ public static <X, Y> MutableList<Pair<X, Y>> zip( List<X> list, Iterable<Y> iterable) { return ListIterate.zip(list, iterable, FastList.<Pair<X, Y>>newList()); } /** * @see Iterate#zip(Iterable, Iterable, Collection) */ public static <X, Y, R extends Collection<Pair<X, Y>>> R zip( List<X> list, Iterable<Y> iterable, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.zip(list, iterable, target); } return IterableIterate.zip(list, iterable, target); } /** * @see Iterate#zipWithIndex(Iterable) */ public static <T> MutableList<Pair<T, Integer>> zipWithIndex(List<T> list) { return ListIterate.zipWithIndex(list, FastList.<Pair<T, Integer>>newList(list.size())); } /** * @see Iterate#zipWithIndex(Iterable, Collection) */ public static <T, R extends Collection<Pair<T, Integer>>> R zipWithIndex( List<T> list, R target) { if (list instanceof RandomAccess) { return RandomAccessListIterate.zipWithIndex(list, target); } return IterableIterate.zipWithIndex(list, target); } /** * @see ListIterable#takeWhile(Predicate) */ public static <T> MutableList<T> takeWhile(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.takeWhile(list, predicate); } MutableList<T> result = FastList.newList(); for (T t : list) { if (predicate.accept(t)) { result.add(t); } else { return result; } } return result; } /** * @see ListIterable#dropWhile(Predicate) */ public static <T> MutableList<T> dropWhile(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.dropWhile(list, predicate); } MutableList<T> result = FastList.newList(); Iterator<T> iterator = list.iterator(); while (iterator.hasNext()) { T each = iterator.next(); if (!predicate.accept(each)) { result.add(each); while (iterator.hasNext()) { T eachNotDropped = iterator.next(); result.add(eachNotDropped); } return result; } } return result; } /** * @see ListIterable#partitionWhile(Predicate) */ public static <T> PartitionMutableList<T> partitionWhile(List<T> list, Predicate<? super T> predicate) { if (list instanceof RandomAccess) { return RandomAccessListIterate.partitionWhile(list, predicate); } PartitionMutableList<T> result = new PartitionFastList<T>(); MutableList<T> selected = result.getSelected(); MutableList<T> rejected = result.getRejected(); Iterator<T> iterator = list.iterator(); while (iterator.hasNext()) { T each = iterator.next(); if (predicate.accept(each)) { selected.add(each); } else { rejected.add(each); while (iterator.hasNext()) { rejected.add(iterator.next()); } return result; } } return result; } }