ProjectAres/Util/core/src/main/java/tc/oc/commons/core/ListUtils.java

125 lines
4.1 KiB
Java

package tc.oc.commons.core;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import gnu.trove.list.TIntList;
import com.google.common.reflect.TypeToken;
import tc.oc.commons.core.reflect.Methods;
import tc.oc.commons.core.stream.Collectors;
import tc.oc.commons.core.util.Streams;
/** List-related utilities. */
public class ListUtils {
/**
* Creates a union from all of the specified {@link List}s.
*
* @param lists The {@link List}s.
* @param <T> The type of {@link List}s.
* @return The union.
*/
@SafeVarargs
public static <T> List<T> union(List<T>... lists) {
List<T> newList = new LinkedList<>();
for (List<T> list : lists) {
newList.addAll(list);
}
return newList;
}
public static int indexOf(List<?> list, Object element, int begin, int end) {
begin = Math.min(begin, list.size());
end = Math.min(end, list.size());
if(begin == 0 && end == list.size()) return list.indexOf(element);
for(int i = begin; i < end; i++) {
if(Objects.equals(element, list.get(i))) return i;
}
return -1;
}
public static int indexOf(List<?> list, Object element, int begin) {
return indexOf(list, element, begin, list.size());
}
public static boolean contains(List<?> list, Object element, int begin, int end) {
return indexOf(list, element, begin, end) != -1;
}
public static boolean contains(List<?> list, Object element, int begin) {
return contains(list, element, begin, list.size());
}
public static <T> T randomElement(List<? extends T> list, Random random) {
if(list.isEmpty()) throw new IndexOutOfBoundsException("List is empty");
return list.get(random.nextInt(list.size()));
}
public static <T> List<T> append(List<T> list, T... elements) {
if(elements.length == 0) {
return list;
} else {
final ImmutableList.Builder<T> builder = ImmutableList.builder();
builder.addAll(list);
builder.add(elements);
return builder.build();
}
}
public static <E> int lexicalCompare(List<? extends E> a, List<? extends E> b, Comparator<? super E> comp) {
final int size = Math.min(a.size(), b.size());
for(int i = 0; i < size; i++) {
final int c = comp.compare(a.get(i), b.get(i));
if(c != 0) return c;
}
return Integer.compare(a.size(), b.size());
}
public static <E extends Comparable<E>> int lexicalCompare(List<? extends E> a, List<? extends E> b) {
return lexicalCompare(a, b, Comparator.naturalOrder());
}
public static int lexicalCompare(TIntList a, TIntList b) {
final int size = Math.min(a.size(), b.size());
for(int i = 0; i < size; i++) {
final int c = Integer.compare(a.get(i), b.get(i));
if(c != 0) return c;
}
return Integer.compare(a.size(), b.size());
}
private static final Method GET_METHOD = Methods.method(List.class, "get", int.class);
public static <T> TypeToken<T> elementType(TypeToken<? extends List<T>> listType) {
return (TypeToken<T>) listType.method(GET_METHOD).getReturnType();
}
public static <F, T> ImmutableList<T> transformedCopyOf(Iterable<F> source, Function<? super F, ? extends T> transform) {
return Streams.of(source)
.map(transform)
.collect(Collectors.toImmutableList());
}
public static <T> ImmutableList<T> filteredCopyOf(Iterable<T> source, Predicate<? super T> filter) {
return Streams.of(source)
.filter(filter)
.collect(Collectors.toImmutableList());
}
public static <T> Optional<T> getIfPresent(List<T> list, int index) {
try {
return Optional.of(list.get(index));
} catch(IndexOutOfBoundsException e) {
return Optional.empty();
}
}
}