/*
* Licensed to Crate under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership. Crate licenses this file
* to you 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.
*
* However, if you have executed another commercial license agreement
* with Crate these terms will supersede the license and you may use the
* software solely pursuant to the terms of the relevant commercial
* agreement.
*/
package io.crate.collections;
import com.google.common.collect.Lists;
import javax.annotation.Nullable;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Lists2 {
/**
* Create a new list that contains the elements of both arguments
*/
public static <T> List<T> concat(Collection<? extends T> list1, Collection<? extends T> list2) {
ArrayList<T> list = new ArrayList<>(list1.size() + list2.size());
list.addAll(list1);
list.addAll(list2);
return list;
}
public static <T> List<T> concatUnique(List<? extends T> list1, List<? extends T> list2) {
List<T> result = new ArrayList<>(list1.size() + list2.size());
result.addAll(list1);
for (T item : list2) {
if (!list1.contains(item)) {
result.add(item);
}
}
return result;
}
/**
* Apply the replace function on each item of the list and replaces the item.
*
* This is similar to {@link Lists#transform(List, com.google.common.base.Function)}, but instead of creating a
* view on a backing list this function is actually mutating the provided list
*/
public static <T> void replaceItems(@Nullable List<T> list, Function<? super T, ? extends T> replaceFunction) {
if (list == null || list.isEmpty()) {
return;
}
ListIterator<T> it = list.listIterator();
while (it.hasNext()) {
it.set(replaceFunction.apply(it.next()));
}
}
/**
* Create a copy of the given list with {@code replaceFunc} applied on each item.
* Opposed to {@link java.util.stream.Stream#map(Function)} / {@link Collectors#toList()} this minimizes allocations.
*/
public static <T> List<T> copyAndReplace(List<T> list, Function<? super T, ? extends T> replaceFunc) {
List<T> copy = new ArrayList<T>(list.size());
for (T item : list) {
copy.add(replaceFunc.apply(item));
}
return copy;
}
/**
* Return the first element of a list or raise an IllegalArgumentException if there are more than 1 items.
*
* Similar to {@link com.google.common.collect.Iterables#getOnlyElement(Iterable)}, but avoids an iterator allocation
*
* @throws NoSuchElementException If the list is empty
* @throws IllegalArgumentException If the list has more than 1 element
*/
public static <T> T getOnlyElement(List<T> items) {
switch (items.size()) {
case 0:
throw new NoSuchElementException("List is empty");
case 1:
return items.get(0);
default:
throw new IllegalArgumentException("Expected 1 element, got: " + items.size());
}
}
}