StreamUtils


import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author lierlin
 * @date 2019-04-23
 */
public class StreamUtils {

    /**
     * 把list对象中的一个字段转换为list
     *
     * @param list
     * @param mapper
     * @param <R>
     * @param <T>
     * @return
     */
    public static <R, T> List<R> collectToList(List<T> list, Function<? super T, ? extends R> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(mapper).distinct().collect(Collectors.toList());
    }

    /**
     * 把list对象中的一个字段转换为set
     *
     * @param list
     * @param mapper
     * @param <R>
     * @param <T>
     * @return
     */
    public static <R, T> Set<R> collectToSet(List<T> list, Function<? super T, ? extends R> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashSet<>();
        }
        return list.stream().map(mapper).collect(Collectors.toSet());
    }

    /**
     * 把list对象中的一个字段转换为list
     *
     * @param list
     * @param mapper
     * @param <R>
     * @param <T>
     * @return
     */
    public static <R, T> List<R> collectToList(Collection<T> list, Function<? super T, ? extends R> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(mapper).distinct().collect(Collectors.toList());
    }

    /**
     * 转换为map,key冲突的会抛异常
     *
     * @param list
     * @param mapper
     * @param <R>
     * @param <T>
     * @return
     */
    public static <R, T> Map<R, T> collectToMap(List<T> list, Function<? super T, ? extends R> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(mapper, Function.identity()));
    }

    /**
     * 转换为map,key冲突的话使用后一个
     *
     * @param list
     * @param mapper
     * @param <R>
     * @param <T>
     * @return
     */
    public static <R, T> Map<R, T> collectToMapUseAfter(List<T> list, Function<? super T, ? extends R> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(mapper, Function.identity(), (before, after) -> after));
    }

    /**
     * 转换为map,key冲突的话使用后一个
     *
     * @param list
     * @param keyMapper
     * @param valueMapper
     * @param <R>
     * @param <U>
     * @param <T>
     * @return
     */
    public static <R, U, T> Map<R, U> collectToMapUseAfter(List<T> list, Function<? super T, ? extends R> keyMapper,
                                                           Function<? super T, ? extends U> valueMapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(keyMapper, valueMapper, (before, after) -> after));
    }

    /**
     * 转换为map,key冲突的话使用前一个
     *
     * @param list
     * @param mapper
     * @param <R>
     * @param <T>
     * @return
     */
    public static <R, T> Map<R, T> collectToMapUseBefore(List<T> list, Function<? super T, ? extends R> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(mapper, Function.identity(), (before, after) -> before));
    }

    /**
     * 根据一个字段groupBy
     *
     * @param list
     * @param mapper
     * @param <R>
     * @param <T>
     * @return
     */
    public static <R, T> Map<R, List<T>> groupBy(List<T> list, Function<? super T, ? extends R> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.groupingBy(mapper));
    }

    /**
     * 对集合先分大组,再大组分小组,对小组求和
     *
     * @param list
     * @param groupKeyMapper 大组 key
     * @param mapKeyMapper   小组 key
     * @param sumMapper      求和值
     * @param mergeFunction  合并函数
     * @param <R>            大组 key
     * @param <R2>           小组 key
     * @param <SUM>          求和值
     * @param <T>
     * @return
     */
    public static <R, R2, SUM, T> Map<R, Map<R2, SUM>> groupAndSum(List<T> list,
                                                                   Function<? super T, ? extends R> groupKeyMapper,
                                                                   Function<? super T, ? extends R2> mapKeyMapper,
                                                                   Function<? super T, ? extends SUM> sumMapper,
                                                                   BinaryOperator<SUM> mergeFunction) {

        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<R, Map<R2, SUM>>();
        }

        return list.stream().collect(
            Collectors.groupingBy(groupKeyMapper, Collectors.toMap(mapKeyMapper, sumMapper, mergeFunction)));
    }

    /**
     * 对集合先分大组,再大组分小组,对小组某个元素统计总数
     *
     * @param list
     * @param groupKeyMapper 大组 key
     * @param mapKeyMapper   小组 key
     * @param countMapper    求和值
     * @param <R>            大组 key
     * @param <R2>           小组 key
     * @param <E>            统计总数
     * @param <T>
     * @return
     */
    public static <R, R2, E, T> Map<R, Map<R2, Integer>> groupAndCount(List<T> list,
                                                                       Function<? super T, ? extends R> groupKeyMapper,
                                                                       Function<? super T, ? extends R2> mapKeyMapper,
                                                                       Function<? super T, ? extends E> countMapper) {

        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<R, Map<R2, Integer>>();
        }

        Map<R, List<T>> group = groupBy(list, groupKeyMapper);
        Map<R, Map<R2, Integer>> result = new HashMap<>();
        for (Entry<R, List<T>> entry : group.entrySet()) {
            R rKey = entry.getKey();
            List<T> tList = entry.getValue();
            Map<R2, List<T>> elementGroup = groupBy(tList, mapKeyMapper);

            Map<R2, Integer> tempResultMap = new HashMap<>();
            for (Entry<R2, List<T>> r2ListEntry : elementGroup.entrySet()) {
                R2 elementKey = r2ListEntry.getKey();
                List<T> tElmentList = r2ListEntry.getValue();
                tempResultMap.put(elementKey, count(tElmentList, countMapper));
            }

            result.put(rKey, tempResultMap);
        }

        return result;
    }

    /**
     * 对集合先分大组,对大组某个元素统计总数
     *
     * @param list
     * @param groupKeyMapper 大组 key
     * @param countMapper    求和值
     * @param <R>            大组 key
     * @param <E>            统计总数
     * @param <T>
     * @return
     */
    public static <R, E, T> Map<R, Integer> groupAndCount(List<T> list,
                                                          Function<? super T, ? extends R> groupKeyMapper,
                                                          Function<? super T, ? extends E> countMapper) {

        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<R, Integer>();
        }

        Map<R, List<T>> group = groupBy(list, groupKeyMapper);
        Map<R, Integer> result = new HashMap<>();
        for (Entry<R, List<T>> entry : group.entrySet()) {
            R rKey = entry.getKey();
            List<T> tList = entry.getValue();

            result.put(rKey, count(tList, countMapper));
        }

        return result;
    }

    /**
     * 对每个元素的子集求子集元素分组
     *
     * @param list
     * @param mapper
     * @param elementMapper
     * @param <R>
     * @param <T>
     * @param <E>
     * @return
     */
    public static <R, T, E> Map<E, List<R>> groupElementListBy(List<T> list,
                                                               Function<? super T, ? extends List<R>> mapper,
                                                               Function<? super R, ? extends E> elementMapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().map(mapper).flatMap(Collection::stream).collect(Collectors.groupingBy(elementMapper));

    }

    /**
     * 对每个元素求元素分组得到元素集合
     * 自动过滤空元素
     * 可以自定义Map 的value的收集方式downstream
     *
     * @param <T>
     * @param <E>
     * @param <E2>
     * @param list
     * @param keyMapper
     * @param downstream
     * @return
     */
    public static <T, E, E2> Map<E, List<E2>> groupListElementByElement(List<T> list,
                                                                        Function<? super T, ? extends E> keyMapper,
                                                                        Collector<? super T, ? extends T, List<E2>> downstream) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(keyMapper, downstream));
    }

    /**
     * 对每个元素求元素分组得到元素集合
     * 自动过滤空元素
     *
     * @param list
     * @param keyMapper
     * @param valueCollectorsMapper
     * @param <T>
     * @param <E>
     * @param <E2>
     * @return
     */
    public static <T, E, E2> Map<E, List<E2>> groupListElementByElement(List<T> list,
                                                                        Function<? super T, ? extends E> keyMapper,
                                                                        Function<? super T, ? extends E2> valueCollectorsMapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().filter(Objects::nonNull).collect(
            Collectors.groupingBy(keyMapper, Collectors.mapping(valueCollectorsMapper, Collectors.toList())));
    }

    /**
     * 对每个元素求元素分组得到元素集合
     * 自动过滤空元素
     * 可以自定义Map 的value的收集方式downstream
     *
     * @param <T>
     * @param <E>
     * @param <E2>
     * @param list
     * @param keyMapper
     * @param downstream
     * @return
     */
    public static <T, E, E2> Map<E, Set<E2>> groupSetElementByElement(List<T> list,
                                                                      Function<? super T, ? extends E> keyMapper,
                                                                      Collector<? super T, ? extends T, Set<E2>> downstream) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(keyMapper, downstream));
    }

    /**
     * 对每个元素求元素分组得到元素集合
     * 自动过滤空元素
     *
     * @param list
     * @param keyMapper
     * @param valueCollectorsMapper
     * @param <T>
     * @param <E>
     * @param <E2>
     * @return
     */
    public static <T, E, E2> Map<E, Set<E2>> groupSetElementByElement(List<T> list,
                                                                      Function<? super T, ? extends E> keyMapper,
                                                                      Function<? super T, ? extends E2> valueCollectorsMapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().filter(Objects::nonNull).collect(
            Collectors.groupingBy(keyMapper, Collectors.mapping(valueCollectorsMapper, Collectors.toSet())));
    }

    /**
     * 对每个元素求元素分组得到元素Map
     * 自动过滤空元素
     *
     * @param list
     * @param keyMapper
     * @param valueMapKeyMapper
     * @param valueMapValueMapper
     * @param <T>
     * @param <GROUP>
     * @param <MapKey>
     * @param <MapValue>
     * @return
     */
    public static <T, GROUP, MapKey, MapValue> Map<GROUP, Map<MapKey, MapValue>> groupMapElementByElement(List<T> list,
                                                                                                          Function<?
                                                                                                              super T
                                                                                                              , ?
                                                                                                              extends GROUP> keyMapper,
                                                                                                          Function<?
                                                                                                              super T
                                                                                                              , ?
                                                                                                              extends MapKey> valueMapKeyMapper,
                                                                                                          Function<?
                                                                                                              super T
                                                                                                              , ?
                                                                                                              extends MapValue> valueMapValueMapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().filter(Objects::nonNull).collect(
            Collectors.groupingBy(keyMapper, Collectors.toMap(valueMapKeyMapper, valueMapValueMapper)));
    }

    /**
     * 对每个元素求元素分组得到元素Map
     * 自动过滤空元素
     * 可以自定义Map 的value的收集方式downstream
     *
     * @param <T>
     * @param <GROUP>
     * @param <MapKey>
     * @param <MapValue>
     * @param list
     * @param keyMapper
     * @param downstream
     * @return
     */
    public static <T, GROUP, MapKey, MapValue> Map<GROUP, Map<MapKey, MapValue>> groupMapElementByElement(List<T> list,
                                                                                                          Function<?
                                                                                                              super T
                                                                                                              , ?
                                                                                                              extends GROUP> keyMapper,
                                                                                                          Collector<?
                                                                                                              super T
                                                                                                              , ?
                                                                                                              extends T, Map<MapKey, MapValue>> downstream) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(keyMapper, downstream));
    }

    /**
     * 对每个元素求元素分组得到元素Map
     * 自动过滤空元素
     *
     * @param list
     * @param keyMapper
     * @param valueMapKeyMapper
     * @param valueMapValueMapper
     * @param <T>
     * @param <GROUP>
     * @param <MapKey>
     * @param <MapValue>
     * @return
     */
    public static <T, GROUP, MapKey, MapValue> Map<GROUP, Map<MapKey, MapValue>> groupMapElementByElementAfter(
        List<T> list, Function<? super T, ? extends GROUP> keyMapper,
        Function<? super T, ? extends MapKey> valueMapKeyMapper,
        Function<? super T, ? extends MapValue> valueMapValueMapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().filter(Objects::nonNull).collect(Collectors
            .groupingBy(keyMapper, Collectors.toMap(valueMapKeyMapper, valueMapValueMapper, (before, after) -> after)));
    }

    /**
     * 对每个元素求元素分组得到元素Map
     * 自动过滤空元素
     *
     * @param list
     * @param keyMapper
     * @param valueMapKeyMapper
     * @param valueMapValueMapper
     * @param <T>
     * @param <GROUP>
     * @param <MapKey>
     * @param <MapValue>
     * @return
     */
    public static <T, GROUP, MapKey, MapValue> Map<GROUP, Map<MapKey, MapValue>> groupMapElementByElementBefore(
        List<T> list, Function<? super T, ? extends GROUP> keyMapper,
        Function<? super T, ? extends MapKey> valueMapKeyMapper,
        Function<? super T, ? extends MapValue> valueMapValueMapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(keyMapper,
            Collectors.toMap(valueMapKeyMapper, valueMapValueMapper, (before, after) -> before)));
    }

    /**
     * 把list对象中的一个List类型字段转换为list
     *
     * @param list
     * @param mapper
     * @param <R>
     * @param <T>
     * @return
     */
    public static <R, T> List<R> collectListToList(List<T> list, Function<? super T, ? extends List<R>> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(mapper).flatMap(Collection::stream).collect(Collectors.toList());

    }

    /**
     * 把 T 类型的集合转换成 R 类型的集合返回
     *
     * @param sourceList
     * @param parseFunction
     * @param <R>
     * @param <T>
     * @return
     */
    public static <R, T> List<R> parseList(Collection<T> sourceList, Function<T, R> parseFunction) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return new ArrayList<>();
        }
        return sourceList.stream().filter(Objects::nonNull).map(parseFunction).distinct().collect(Collectors.toList());
    }

    /**
     * 把 T 元素 E 类型的集合转换成 R 类型的集合返回
     *
     * @param sourceList
     * @param mapper
     * @param parseFunction
     * @param <R>
     * @param <E>
     * @param <T>
     * @return
     */
    public static <R, E, T> List<R> parseList(Collection<T> sourceList, Function<? super T, ? extends E> mapper,
                                              Function<E, R> parseFunction) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return new ArrayList<>();
        }
        return sourceList.stream().map(mapper).filter(Objects::nonNull).map(parseFunction).distinct().collect(
            Collectors.toList());
    }

    /**
     * 把一个list对象中的一个String类型的字段组合成一个用逗号分隔的字符串
     *
     * @param sourceList
     * @param mapper
     * @param <T>
     * @return
     */
    public static <T> String join(List<T> sourceList, Function<? super T, ? extends String> mapper) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return null;
        }
        return sourceList.stream().map(mapper).distinct().collect(Collectors.joining(","));
    }

    private static final String COMMA = ",";

    public static List<String> spiltToList(String source) {
        if (StringUtils.isBlank(source)) {
            return null;
        }
        return Stream.of(source.trim().split(COMMA)).collect(Collectors.toList());
    }

    public static String joinComma(List<?> list) {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return StringUtils.join(list, COMMA);
    }

    public static List<Long> spiltToLong(String source) {
        if (StringUtils.isBlank(source)) {
            return null;
        }
        return Stream.of(source.trim().split(COMMA)).map(Long::valueOf).collect(Collectors.toList());
    }

    public static List<Integer> spiltToInteger(String source) {
        if (StringUtils.isBlank(source)) {
            return null;
        }
        return Stream.of(source.trim().split(COMMA)).map(Integer::valueOf).collect(Collectors.toList());
    }

    public static List<BigDecimal> spiltToBigDecimal(String source) {
        if (StringUtils.isBlank(source)) {
            return null;
        }
        return Stream.of(source.trim().split(COMMA)).map(BigDecimal::new).collect(Collectors.toList());
    }

    /**
     * 返回满足过滤条件的list
     *
     * @param sourceList 原list
     * @param predicate  过滤条件
     * @param <T>        过滤之后的list
     * @return
     */
    public static <T> List<T> filterCollectToList(List<T> sourceList, Predicate<? super T> predicate) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return sourceList;
        }
        return sourceList.stream().filter(predicate).collect(Collectors.toList());
    }

    /**
     * 把一个list中的一个bigDecimal类型的字段加起来返回
     *
     * @param list   原list
     * @param mapper bigDecimal字段
     * @param <T>
     * @return 相加的和
     */
    public static <T> BigDecimal bigDecimalSum(List<T> list, Function<? super T, BigDecimal> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.stream().map(mapper).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    public static <T> Integer integerSum(List<T> list, Function<? super T, Integer> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.stream().map(mapper).reduce(Integer::sum).orElse(0);
    }

    public static <T, R> Integer count(List<T> sourceList, Function<? super T, ? extends R> mapper) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return null;
        }
        return Long.valueOf(sourceList.stream().map(mapper).distinct().count()).intValue();
    }

    /**
     * 根据list中的一个int类型的数字字段排序asc,字段为null排在最后
     *
     * @param sourceList 原list
     * @param mapper     Integer字段
     * @param <T>
     * @return 排序后的list
     */
    public static <T> List<T> sortByIntAscAndNullLast(List<T> sourceList,
                                                      Function<? super T, ? extends Integer> mapper) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return new ArrayList<>();
        }
        return sourceList.stream()
            .sorted(Comparator.comparing(mapper, Comparator.nullsLast(Comparator.naturalOrder())))
            .collect(Collectors.toList());
    }

    /**
     * 根据list中的一个Date类型的数字字段排序asc,字段为null排在最后
     *
     * @param sourceList 原list
     * @param mapper     Date字段
     * @param <T>
     * @return 排序后的list
     */
    public static <T> List<T> sortByDateDescAndNullLast(Collection<T> sourceList,
                                                        Function<? super T, ? extends Date> mapper) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return new ArrayList<>();
        }
        return sourceList.stream()
            .sorted(Comparator.comparing(mapper, Comparator.nullsLast(Comparator.naturalOrder())))
            .collect(Collectors.toList());
    }

    /**
     * string转换为int,string为空返回null
     *
     * @param value
     * @return
     */
    public static Integer convertInt(String value) {
        if (StringUtils.isBlank(value)) {
            return null;
        }
        return Integer.valueOf(value);
    }

    /**
     * 校验一个集合是否为空,集货里面的元素都为空的话代表集合也是空的
     *
     * @param collection
     * @param <E>
     * @return
     */
    public static <E> boolean isEmpty(Collection<E> collection) {
        return CollectionUtils.isEmpty(collection) || collection.stream().allMatch(Objects::isNull);
    }

    public static <E> boolean isNotEmpty(Collection<E> collection) {
        return !isEmpty(collection);
    }

    public static <E> void forEachWithIndex(Object[] elements, BiConsumer<Integer, Object> action) {
        if (elements == null) {
            return;
        }

        Objects.requireNonNull(elements);
        Objects.requireNonNull(action);
        int index = 0;
        for (Object element : elements) {
            action.accept(index++, element);
        }
    }

    public static <E> void forEachWithIndex(Iterable<? extends E> elements, BiConsumer<Integer, ? super E> action) {
        if (elements == null) {
            return;
        }
        Objects.requireNonNull(elements);
        Objects.requireNonNull(action);
        int index = 0;
        for (E element : elements) {
            action.accept(index++, element);
        }
    }

    public static <T, R> Map<R, BigDecimal> sumByKey(Collection<T> collection,
                                                     Function<? super T, ? extends R> groupByKey,
                                                     Function<? super T, BigDecimal> sumKey) {
        if (CollectionUtils.isEmpty(collection)) {
            return new HashMap<>();
        }
        Map<R, List<T>> map = collection.stream().collect(Collectors.groupingBy(groupByKey));
        Map<R, BigDecimal> result = new HashMap<>();
        map.forEach((key, list) -> {
            BigDecimal sumResult = list.stream().map(sumKey).reduce(BigDecimal.ZERO, BigDecimal::add);
            result.put(key, sumResult);
        });
        return result;
    }

    /**
     * 获取集合的size,空或者null返回0
     *
     * @param list
     * @return int
     * @date 2020/8/17 4:47 下午
     * @author QinDaoFang
     */
    public static <T> int collectSize(Collection<T> list) {
        if (CollectionUtils.isEmpty(list)) {
            return 0;
        }
        return list.size();
    }

    /**
     * 获取集合的size,空或者null返回0
     *
     * @param list
     * @param mapper
     * @return int
     * @date 2020/8/17 4:47 下午
     * @author QinDaoFang
     */
    public static <T, R> int collectSize(Collection<T> list, Function<? super T, ? extends R> mapper) {
        if (CollectionUtils.isEmpty(list)) {
            return 0;
        }
        if (mapper != null) {
            return (int)list.stream().map(mapper).count();
        }
        return list.size();
    }

    /**
     * 过滤后获得获取集合的size,空或者null返回0
     *
     * @param list
     * @param predicate
     * @return int
     * @date 2020/8/17 4:47 下午
     * @author QinDaoFang
     */
    public static <T, R> int filterAndCollectSize(Collection<T> list, Predicate<? super T> predicate) {
        if (CollectionUtils.isEmpty(list)) {
            return 0;
        }
        if (predicate != null) {
            return (int)list.stream().filter(predicate).count();
        }
        return list.size();
    }

    /**
     * @param map
     * @return java.util.List<V>
     * @date 2020/8/20 2:25 下午
     * @author QinDaoFang
     */
    public static <K, V> List<V> mapValueToList(Map<K, List<V>> map) {
        if (MapUtils.isEmpty(map)) {
            return new ArrayList<>();
        }
        List<V> list = new ArrayList<>();
        map.forEach((k, vs) -> {
            list.addAll(vs);
        });
        return list;
    }

    /**
     * 从一个集合的集合对象中,获取元素的值,组成集合返回
     * List<List<LuDetail></>
     *
     * @param list
     * @param mapper
     * @param elementMapper
     * @param <R>
     * @param <T>
     * @return
     */
    public static <R, T, E> List<E> collectListElementToList(List<T> list,
                                                             Function<? super T, ? extends List<R>> mapper,
                                                             Function<? super R, ? extends E> elementMapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().filter(Objects::nonNull).map(mapper).filter(CollectionUtils::isNotEmpty).flatMap(
            Collection::stream).filter(Objects::nonNull).map(elementMapper).distinct().collect(Collectors.toList());

    }

    /**
     * 找到第一个值,
     *
     * @param list
     * @param predicate
     * @param <T>
     * @return
     */
    public static <T> T findFirstOrNull(List<T> list,
                                        Predicate<? super T> predicate) {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.stream().filter(predicate).findFirst().orElse(null);
    }

    /**
     * 找到第一个值的属性值
     *
     * @param list
     * @param resultMapper
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T, E> E findFirstElementOrNull(List<T> list,
                                                  Function<? super T, ? extends E> resultMapper) {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        T t = list.get(0);
        if (t == null) {
            return null;
        }
        return resultMapper.apply(t);
    }

    /**
     * 找到第一个值的属性值
     *
     * @param list
     * @param resultMapper
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T, E> E findFirstElementOrElse(List<T> list,
                                                  Function<? super T, ? extends E> resultMapper, E defaultValue) {
        if (CollectionUtils.isEmpty(list)) {
            return defaultValue;
        }
        T t = list.get(0);
        if (t == null) {
            return defaultValue;
        }
        return resultMapper.apply(t);
    }

    public static <T, E> List<T> getByElementValue(
        List<T> list,
        Function<? super T, ? extends E> resultMapper, E compareValue) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        Map<E, List<T>> map = groupBy(list, resultMapper);

        return map.get(compareValue);
    }

    /**
     * 获取map的第一个值,
     *
     * @param <T>
     * @return
     */
    public static <T> T findMapFirstValue(Map<?, T> map) {
        Map.Entry<?, T> entrySet = map.entrySet().stream().findFirst().orElse(null);
        return entrySet != null ? entrySet.getValue() : null;
    }

    public static <T> T get(Object object, int index) {

        if (object instanceof Map) {
            Map map = (Map)object;
            if (MapUtils.isEmpty(map)) {
                return null;
            }
        } else if (object instanceof List) {
            if (CollectionUtils.isEmpty((List)object)) {
                return null;
            }
        } else if (object instanceof Object[]) {
            if (((Object[])object) == null || ((Object[])object).length < 1) {
                return null;
            }
        } else if (object instanceof Iterator) {
            Iterator it = (Iterator)object;
            if (it == null || !it.hasNext()) {
                return null;
            }
        } else if (object instanceof Collection) {
            if (CollectionUtils.isEmpty((Collection)object)) {
                return null;
            }
        } else if (object instanceof Enumeration) {
            Enumeration it = (Enumeration)object;
            if (!it.hasMoreElements()) {
                return null;
            }
        }
        return (T)CollectionUtils.get(object, index);
    }

    public static <T> T getFirstOrNull(Object object) {
        return getOrElse(object, 0, null);
    }

    public static <T> T getOrNull(Object object, int index) {
        return getOrElse(object, index, null);
    }

    public static <T> T getOrElse(Object object, int index, T defaultValue) {

        if (object == null) {
            return defaultValue;
        }

        if (object instanceof Map) {
            Map map = (Map)object;
            if (MapUtils.isEmpty(map)) {
                return defaultValue;
            }
        } else if (object instanceof List) {
            if (CollectionUtils.isEmpty((List)object)) {
                return defaultValue;
            }
        } else if (object instanceof Object[]) {
            if (((Object[])object) == null || ((Object[])object).length < 1) {
                return defaultValue;
            }
        } else if (object instanceof Iterator) {
            Iterator it = (Iterator)object;
            if (it == null || !it.hasNext()) {
                return defaultValue;
            }
        } else if (object instanceof Collection) {
            if (CollectionUtils.isEmpty((Collection)object)) {
                return defaultValue;
            }
        } else if (object instanceof Enumeration) {
            Enumeration it = (Enumeration)object;
            if (!it.hasMoreElements()) {
                return defaultValue;
            }
        }

        T result = (T)CollectionUtils.get(object, index);
        if (result == null) {
            return defaultValue;
        }
        return result;
    }

    /**
     * @param supplier
     * @param needInvoke
     * @param notInvokeDefaultValue
     * @param <R>
     * @return
     */
    public static <R> R thenInvoke(final Supplier<R> supplier, final boolean needInvoke,
                                   final R notInvokeDefaultValue) {
        if (!needInvoke) {
            return notInvokeDefaultValue;
        }
        return supplier.get();

    }

    /**
     * 两个数组抽象想减
     *
     * @param originalList
     * @param originalMapper
     * @param subtractedList
     * @param subtractedMapper
     * @param <R>
     * @param <T>
     * @param <S>
     * @return
     */
    public static <R, T, S> List<R> subtractToList(Collection<T> originalList,
                                                   Function<? super T, ? extends R> originalMapper,
                                                   Collection<S> subtractedList,
                                                   Function<? super S, ? extends R> subtractedMapper) {
        if (CollectionUtils.isEmpty(originalList)) {
            return Collections.emptyList();
        }
        if (CollectionUtils.isEmpty(subtractedList)) {
            return collectToList(originalList, originalMapper);
        }
        return (List<R>)CollectionUtils.subtract(collectToList(originalList, originalMapper),
            collectToList(subtractedList, subtractedMapper));
    }

    /**
     * @param originalList
     * @param originalMapper
     * @param subtractedList
     * @param subtractedMapper
     * @param <R>
     * @param <T>
     * @param <S>
     * @return
     */
    public static <R, T, S> List<T> subtractByElement(Collection<T> originalList,
                                                      Function<? super T, ? extends R> originalMapper,
                                                      Collection<S> subtractedList,
                                                      Function<? super S, ? extends R> subtractedMapper) {
        if (CollectionUtils.isEmpty(originalList)) {
            return new ArrayList<>();
        }
        if (CollectionUtils.isEmpty(subtractedList)) {
            return new ArrayList<>(originalList);
        }

        List<R> remainedSourceList = subtractToList(originalList, originalMapper, subtractedList, subtractedMapper);
        if (CollectionUtils.isEmpty(remainedSourceList)) {
            return new ArrayList<>();
        }
        Map<R, R> keyMap = collectToMapUseAfter(remainedSourceList, r -> r);
        List<T> resultList = new ArrayList<>();
        for (T t : originalList) {
            R r = originalMapper.apply(t);
            if (keyMap.containsKey(r)) {
                resultList.add(t);
            }
        }

        return resultList;
    }

    /**
     * 返回数组元素
     *
     * @param list
     * @param computeRepeatMapperList
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T, E> Set<T> computeRepeatList(Collection<T> list,
                                                  Function<? super T, ? extends E>... computeRepeatMapperList) {

        if (CollectionUtils.isEmpty(list)) {
            return new HashSet<>();
        }
        HashSet<String> eHashSet = new HashSet<>();
        Set<T> resultSet = new HashSet<>();
        for (T t : list) {

            String key = getMapperListKey(t, computeRepeatMapperList);
            if (!eHashSet.add(key)) {
                resultSet.add(t);
            }
        }
        return resultSet;
    }

    /**
     * 返回数组元素中指定值
     *
     * @param list
     * @param resultMapper
     * @param computeRepeatMapperList
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T, E, R> Set<R> computeRepeatListElement(Collection<T> list,
                                                            Function<? super T, ? extends R> resultMapper,
                                                            Function<? super T, ? extends E>... computeRepeatMapperList) {

        if (CollectionUtils.isEmpty(list)) {
            return new HashSet<>();
        }
        HashSet<String> eHashSet = new HashSet<>();
        Set<R> resultSet = new HashSet<>();
        for (T t : list) {

            String key = getMapperListKey(t, computeRepeatMapperList);
            if (!eHashSet.add(key)) {
                R r = resultMapper.apply(t);
                resultSet.add(r);
            }
        }
        return resultSet;
    }

    /**
     * @param t
     * @param mapperList
     * @return java.lang.String
     * @date 2020/12/20 4:19 下午
     * @author QinDaoFang
     */
    public static <R, T> String getMapperListKey(T t, Function<? super T, ? extends R>... mapperList) {
        if (t == null) {
            return null;
        }
        StringBuilder keyAll = new StringBuilder();
        int index = 0;
        for (Function<? super T, ? extends R> key : mapperList) {
            R keyR = key.apply(t);
            if (keyR == null) {
                keyAll.append(keyR);
            } else {
                keyAll.append(keyR.toString());
            }
            if (index < mapperList.length - 1) {
                keyAll.append('-');
            }

            index++;
        }
        return keyAll.toString();
    }

    /**
     * @param list
     * @param mapperList
     * @return java.util.Map<java.lang.String, T>
     * @date 2020/12/20 4:19 下午
     * @author QinDaoFang
     */
    public static <R, T> Map<String, T> collectToMultipleKeyMap(List<T> list,
                                                                Function<? super T, ? extends R>... mapperList) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().collect(Collectors.toMap(t -> getMapperListKey(t, mapperList), Function.identity()));
    }

    public static <R, T> Map<String, T> collectToMultipleKeyMapUseAfter(List<T> list,
                                                                        Function<? super T, ? extends R>... mapperList) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().collect(
            Collectors.toMap(t -> getMapperListKey(t, mapperList), Function.identity(), (before, after) -> after));
    }

    public static <R, T> Map<String, T> collectToMultipleKeyMapUseBefore(List<T> list,
                                                                         Function<? super T, ? extends R>... mapperList) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        return list.stream().collect(
            Collectors.toMap(t -> getMapperListKey(t, mapperList), Function.identity(), (before, after) -> before));
    }

    public static boolean sizeBigThen(Collection list, int compareNum) {
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        }

        return list.size() > compareNum;
    }

    public static Integer maxOrZero(Collection<Integer> values) {

        if (CollectionUtils.isEmpty(values)) {
            return 0;
        }
        return Collections.max(values);
    }

    public static <T, S extends Comparable<? super S>, R> R maxOrNull(List<T> list,
                                                                      Function<? super T, ? extends S> sortMapper,
                                                                      Function<? super T, R> resultMapper) {

        if (org.apache.commons.collections.CollectionUtils.isEmpty(list)) {
            return null;
        }

        return list.stream().max(Comparator.comparing(sortMapper, Comparator.nullsLast(Comparator.naturalOrder())))
            .map(resultMapper).orElse(null);
    }

    public static <T, S extends Comparable<? super S>, R> R maxOrOther(List<T> list,
                                                                       Function<? super T, ? extends S> sortMapper,
                                                                       Function<? super T, R> resultMapper,
                                                                       R defaultValue) {

        if (CollectionUtils.isEmpty(list)) {
            return defaultValue;
        }

        return list.stream().max(Comparator.comparing(sortMapper, Comparator.nullsLast(Comparator.naturalOrder())))
            .map(resultMapper).orElse(defaultValue);
    }

    public static <T, S extends Comparable<? super S>, R> R maxOrOther(List<T> list,
                                                                       Function<? super T, ? extends S> sortMapper,
                                                                       Function<? super T, R> resultMapper,
                                                                       Comparator<? super S> sortComparator,
                                                                       R r) {

        if (CollectionUtils.isEmpty(list)) {
            return r;
        }

        return list.stream().max(
            Comparator.comparing(sortMapper, Comparator.nullsLast(sortComparator))).map(resultMapper).orElse(r);
    }

    public static <T, S extends Comparable<? super S>, R> R minOrNull(List<T> list,
                                                                      Function<? super T, ? extends S> sortMapper,
                                                                      Function<? super T, R> resultMapper) {

        if (CollectionUtils.isEmpty(list)) {
            return null;
        }

        return list.stream().min(Comparator.comparing(sortMapper, Comparator.nullsLast(Comparator.naturalOrder())))
            .map(resultMapper).orElse(null);
    }

    public static <T, S extends Comparable<? super S>, R> R minOrOther(List<T> list,
                                                                       Function<? super T, ? extends S> sortMapper,
                                                                       Function<? super T, R> resultMapper,
                                                                       R defaultValue) {

        if (CollectionUtils.isEmpty(list)) {
            return defaultValue;
        }

        return list.stream().min(Comparator.comparing(sortMapper, Comparator.nullsLast(Comparator.naturalOrder())))
            .map(resultMapper).orElse(defaultValue);
    }

    public static <T, S extends Comparable<? super S>, R> R minOrOther(List<T> list,
                                                                       Function<? super T, ? extends S> sortMapper,
                                                                       Function<? super T, R> resultMapper,
                                                                       Comparator<? super S> sortComparator,
                                                                       R r) {

        if (CollectionUtils.isEmpty(list)) {
            return r;
        }

        return list.stream().min(
            Comparator.comparing(sortMapper, Comparator.nullsLast(sortComparator))).map(resultMapper).orElse(r);
    }

    public static <R, T, E, TK> Map<E, List<T>> groupByElementKey(List<T> list,
                                                                  Function<? super T, ? extends List<R>> childMapper,
                                                                  Function<? super R, ? extends E> childElementMapper,
                                                                  Function<? super T, ? extends TK> parentKeyMapper,
                                                                  Function<? super R, ? extends TK> childElementEqualParentKeyMapper) {
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }

        Map<TK, List<T>> parentGroup = StreamUtils.groupBy(list, parentKeyMapper);
        Map<E, List<R>> childGroup = StreamUtils.groupElementListBy(list, childMapper, childElementMapper);

        Map<E, List<T>> resultMap = new HashMap<>();
        for (Entry<E, List<R>> childEntry : childGroup.entrySet()) {
            E key = childEntry.getKey();
            List<R> childList = childEntry.getValue();
            List<TK> tkList = StreamUtils.collectToList(childList, childElementEqualParentKeyMapper);
            List<T> allParentList = StreamUtils.mapListToListByMoreKey(parentGroup, tkList);

            resultMap.put(key, allParentList);
        }

        return resultMap;
    }

    private static <K, V> List<V> mapToListByMoreKey(Map<K, V> map, List<K> mapKeyList) {
        if (MapUtils.isEmpty(map)) {
            return new ArrayList<>();
        }

        if (CollectionUtils.isEmpty(mapKeyList)) {
            return new ArrayList<>();
        }

        return mapKeyList.stream().map(map::get).collect(Collectors.toList());
    }

    private static <K, V> List<V> mapListToListByMoreKey(Map<K, List<V>> map, List<K> mapKeyList) {
        if (MapUtils.isEmpty(map)) {
            return new ArrayList<>();
        }

        if (CollectionUtils.isEmpty(mapKeyList)) {
            return new ArrayList<>();
        }

        return mapKeyList.stream().map(map::get).flatMap(Collection::stream).collect(Collectors.toList());
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值