package ltd.beihu.core.tools.utils; import ltd.beihu.core.tools.function.BiConsumer; import ltd.beihu.core.tools.function.Generator; import ltd.beihu.core.tools.function.TwoArgFunc; import java.lang.reflect.Array; import java.util.*; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.IntFunction; import java.util.stream.Collectors; /** * @Project: [ops] * @Description: [集合扩展性操作] * @Author: [toming] * @CreateDate: [10/26/16 2:15 PM] * @Version: [v1.0] */ public final class CollectionExtendUtil { /** * Gets a Collection size or {@code 0} if the Collection is * {@code null}. * * @param collection -a Collection or {@code null} * @return Collection size or {@code 0} if the Collection is * {@code null}. */ public static int size(Collection collection) { return collection == null ? 0 : collection.size(); } public static <T> T getOne(Collection<T> collection) { return CollectionUtils.isEmpty(collection) ? null : collection.iterator().next(); } public static Object unboxIfSingle(Collection collection) { int size = size(collection); if (size == 0) return null; if (size == 1) { return getOne(collection); } else { return collection; } } /** * <p>Compares two Collection by size, returning {@code true} if their size are same.</p> * <p>if the Collection is null,it's size will be zero</p> * <pre> * sizeEqual(null, null) = true * sizeEqual(null, empty) = true * sizeEqual(empty, empty) = true * sizeEqual([1,2], [1,2,3]) = false * </pre> * * @param one -the first Collection, may be {@code null} * @param other -the second Collection, may be {@code null} * @return */ public static boolean sizeEqual(Collection one, Collection other) { return size(one) == size(other); } public static <T, K> Map<K, List<T>> group(Collection<T> collection, Function<T, K> groupBy) { return group(collection, groupBy, ArrayList::new); } public static <T, K, V extends Collection<T>> Map<K, V> group( Collection<T> collection, Function<T, K> groupBy, Generator<V> generator) { Map<K, V> result = new HashMap<K, V>(); for (T t : collection) { K key = groupBy.apply(t); V val = result.computeIfAbsent(key, k -> generator.generate()); val.add(t); } return result; } public static <T, K, VN, V extends Collection<VN>> Map<K, V> group( Collection<T> collection, Function<T, K> groupBy, Function<T, VN> valueHandle, Generator<V> generator) { Map<K, V> result = new HashMap<K, V>(); for (T t : collection) { K key = groupBy.apply(t); V val = result.computeIfAbsent(key, k -> generator.generate()); val.add(valueHandle.apply(t)); } return result; } /** * <p>convert collection to map</p> * * @param collection -a Collection * @param keyHandle -handle which will be used to get key from element in the collection * @param <T> -the type of collection * @param <K> -the type of target key * @return -a map created by collection */ public static <T, K> Map<K, T> collectionToMap(Collection<T> collection, Function<T, K> keyHandle) { Map<K, T> map = new HashMap<>(); // for (T t : collection) { // map.put(keyHandle.apply(t), t); // } collection.stream().forEach(t -> map.put(keyHandle.apply(t), t)); return map; } /** * <p>convert collection to map</p> * * @param collection -a Collection * @param keyHandle -handle which will be used to get key from element in the collection * @param valHandle -handle which will be used to get val from element in the collection * @param <T> -the type of collection * @param <K> -the type of target key * @return -a map created by collection */ public static <T, K, V> Map<K, V> collectionToMap(Collection<T> collection, Function<T, K> keyHandle, Function<T, V> valHandle) { Map<K, V> map = new HashMap<>(); collection.stream().forEach(t -> map.put(keyHandle.apply(t), valHandle.apply(t))); return map; } /** * <p>convert map to list</p> * * @param map -a map * @param keyHandle -handle which will get a new result from keyValuePir * @param <T> -the type of result * @param <K> -the type of key * @param <V> -the type of value * @return -a list created by a map */ public static <T, K, V> List<T> mapToList(Map<K, V> map, TwoArgFunc<K, V, T> keyHandle) { return map.keySet().stream().map(k -> keyHandle.apply(k, map.get(k))).collect(Collectors.toList()); } public static void foreach(Object object, Consumer<Object> consumer) { foreach(object, consumer, (a, b) -> consumer.accept(org.apache.commons.lang3.tuple.Pair.of(a, b))); } public static void foreach(Object object, Consumer<Object> consumer, BiConsumer<Object, Object> entryConsumer) { if (object instanceof Map) { Set<Map.Entry> entrys = ((Map) object).entrySet(); for (Map.Entry entry : entrys) { entryConsumer.accept(entry.getKey(), entry.getValue()); } } else if (object instanceof Collection) { ((Collection) object).forEach(consumer); } else if (object instanceof Object[]) { for (Object o : ((Object[]) object)) { consumer.accept(o); } } else if (object instanceof Iterator) { Iterator it = (Iterator) object; while (it.hasNext()) { consumer.accept(it.next()); } } else if (object instanceof Enumeration) { Enumeration it = (Enumeration) object; while (it.hasMoreElements()) { consumer.accept(it.nextElement()); } } else { consumer.accept(null); } } /** * 对数组进行map操作 * * @param tArray -源数组 * @param mapper -map函数 * @param generator -结果构造器 * @param <T> -源类型 * @param <R> -结果类型 * @return -结果集数组 */ public static <T, R> R[] map(T[] tArray, Function<? super T, ? extends R> mapper, IntFunction<R[]> generator) { return tArray == null ? generator.apply(0) : Arrays.stream(tArray).map(mapper).toArray(generator); } /** * 对List进行map操作 * * @param tList -源List * @param mapper -map函数 * @param <T> -源类型 * @param <R> -结果类型 * @return -结果集数组 */ public static <T, R> List<R> map(List<T> tList, Function<? super T, ? extends R> mapper) { return tList == null ? null : tList.stream().map(mapper).collect(Collectors.toList()); } public static <T> Object[] erasure(T[] array) { if (array == null) return null; Object[] objects = new Object[array.length]; System.arraycopy(array, 0, objects, 0, array.length); return objects; } @SuppressWarnings("unchecked") public static <T> T[] toArray(Collection<? extends T> collection, Class<T> cls) { T[] array = (T[]) Array.newInstance(cls, collection.size()); return collection.toArray(array); } }