package co.codewizards.cloudstore.core.util; import static co.codewizards.cloudstore.core.util.AssertUtil.*; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; public final class CollectionUtil { private CollectionUtil() { } /** * Splits a given {@code Set} into multiple {@code Set}s, each with the maximum size specified. * <p> * For example, imagine a {@code Set} with 26 elements. Invoking this method with {@code maxSize == 10} * will cause a resulting {@code List} having 3 {@code Set} elements. The first 2 of the {@code Set} * elements each have 10 elements, while the 3rd one will have only 6 elements. * <p> * Please note that the order is maintained ({@link LinkedHashSet} is used internally for each * segment-{@code Set}). * * @param inputSet the {@code Set} to be split. Must not be <code>null</code>. This {@code Set} is not * modified in any way by this method. * @param maxSize the maximum size of each resulting segment-{@code Set}. Must be greater than 0. * @return a {@code List} containing all elements from the given {@code inputSet} in the same order, * grouped in groups each not greater than {@code maxSize}. Never <code>null</code>. * @see #splitList(List, int) */ public static <E> List<Set<E>> splitSet(final Set<E> inputSet, final int maxSize) { assertNotNull(inputSet, "inputSet"); if (maxSize < 1) throw new IllegalArgumentException("maxSize < 1"); final List<Set<E>> result = new ArrayList<>(inputSet.size() / maxSize + 1); Set<E> current = null; for (final E element : inputSet) { if (current == null || current.size() >= maxSize) { current = new LinkedHashSet<E>(maxSize); result.add(current); } current.add(element); } return result; } /** * Splits a given {@code List} into multiple {@code List}s, each with the maximum size specified. * <p> * For example, imagine a {@code List} with 26 elements. Invoking this method with {@code maxSize == 10} * will cause a resulting {@code List} having 3 {@code List} elements. The first 2 of the {@code List} * elements each have 10 elements, while the 3rd one will have only 6 elements. * <p> * Please note that the order is maintained. * * @param inputList the {@code List} to be split. Must not be <code>null</code>. This {@code List} is not * modified in any way by this method. * @param maxSize the maximum size of each resulting segment-{@code List}. Must be greater than 0. * @return a {@code List} containing all elements from the given {@code inputList} in the same order, * grouped in groups each not greater than {@code maxSize}. Never <code>null</code>. * @see #splitSet(Set, int) */ public static <E> List<List<E>> splitList(final List<E> inputList, final int maxSize) { assertNotNull(inputList, "inputList"); if (maxSize < 1) throw new IllegalArgumentException("maxSize < 1"); final List<List<E>> result = new ArrayList<>(inputList.size() / maxSize + 1); List<E> current = null; for (final E element : inputList) { if (current == null || current.size() >= maxSize) { current = new ArrayList<E>(maxSize); result.add(current); } current.add(element); } return result; } public static <E> List<E> nullToEmpty(final List<E> list) { return list == null ? Collections.<E>emptyList() : list; } public static <E> Set<E> nullToEmpty(final Set<E> set) { return set == null ? Collections.<E>emptySet() : set; } public static <E> Collection<E> nullToEmpty(final Collection<E> collection) { return collection == null ? Collections.<E>emptyList() : collection; } public static <E> Iterator<E> nullToEmpty(final Iterator<E> iterator) { return iterator == null ? Collections.<E>emptyList().iterator() : iterator; } @SafeVarargs public static <E> List<E> asListWithoutNullElements(final E... elements) { if (elements == null) return Collections.emptyList(); final ArrayList<E> result = new ArrayList<>(elements.length); for (final E element : elements) { if (element != null) result.add(element); } result.trimToSize(); return Collections.unmodifiableList(result); } }