package com.artfess.yhxt.util;


import org.apache.commons.collections.CollectionUtils;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @project:
 * @author: Naf
 * @date: 2023-04-14
 * @desc:
 **/
@SuppressWarnings("unchecked")
public class StreamUtil {

    private StreamUtil() {
        throw new IllegalStateException("该对象不能实例化");
    }


    /**
     * 求集合并集
     * @param list1
     * @param list2
     * @return
     */
    public static List<String> getUnion(List<String> list1, List<String> list2){
        if(null == list1 || list1.isEmpty()){
            return list2;
        }
         if(null == list2 || list2.isEmpty()){
            return list1;
        }
        List<String> union = (List<String>) CollectionUtils.union(list1, list2);
        return union;
    }
    //获取两个集合交集
    public static List<String> getIntersection(List<String> list1,List<String> list2){
        List<String> intersection = (List<String>)CollectionUtils.intersection(list1, list2);
        return intersection;
    }
    //获取两个集合交集的补集 即 list1 + list2 - 交集
    public static List<String> getDisjunction(List<String> list1,List<String> list2){
        List<String> disjunction = (List<String>)CollectionUtils.disjunction(list1, list2);
        return disjunction;
    }

    //获取两个集合的差集 list1 - 交集
    public static List<String> getSubtract(List<String> list1,List<String> list2){
        List<String> subtract = (List<String>)CollectionUtils.subtract(list1, list2);
        return subtract;
    }


    /**
     * 执行Consumer类方法 (简化if then set)
     * @author naf
     */
    public static <A> void execSetter(boolean b, Consumer<A> consumer, A a) {
        if (b) {
            consumer.accept(a);
        }
    }

    /**
     * 执行Supplier类方法 (简化if then get)
     * @author naf
     */
    public static <A> void execGetter(boolean b, Supplier<A> supplier) {
        if (b) {
            supplier.get();
        }
    }

    /**
     * 提取某一个字段
     * @author naf
     * @return List
     */
    public static <O, R> List<R> toList(Collection<O> collection, Function<? super O, ? extends R> function) {
        if (collection == null) {
            return new ArrayList<>();
        }
        return collection.stream().filter(Objects::nonNull).map(function).filter(Objects::nonNull).collect(Collectors.toList());
    }

    /**
     * 提取某一个字段
     * @author naf
     * @return Set
     */
    public static <O, R> Set<R> toSet(Collection<O> collection, Function<? super O, ? extends R> function) {
        if (collection == null) {
            return new HashSet<>();
        }
        return collection.stream().filter(Objects::nonNull).map(function).filter(Objects::nonNull).collect(Collectors.toSet());
    }

    /**
     * 转map
     * @author naf
     * @return Map<K, V>
     */
    public static <O, K, V> Map<K, V> toMap(Collection<O> list,
                                            Function<? super O, ? extends K> keyFunc,
                                            Function<? super O, ? extends V> valFunc) {
        if (list == null) {
            return new HashMap<>();
        }
        return list.stream().filter(Objects::nonNull).collect(Collectors.toMap(keyFunc, valFunc, (o1, o2) -> o1));
    }

    /**
     * 转map
     *
     * @return Map<K, V>
     * @author naf
     */
    public static <O, K> Map<K, O> toMap(Collection<O> list,
                                         Function<? super O, ? extends K> keyFunc) {
        if (list == null) {
            return new HashMap<>();
        }
        return list.stream().filter(Objects::nonNull).collect(Collectors.toMap(keyFunc, o -> o, (o1, o2) -> o1));
    }

    /**
     * 保留满足条件的
     * @author naf
     * @return List
     */
    public static <O> List<O> filter(List<O> list, Predicate<? super O> predicate) {
        if (list == null) {
            return new ArrayList<>();
        }
        return list.stream().filter(Objects::nonNull).filter(predicate).collect(Collectors.toList());
    }


    /**
     * @description 将集合进行分组
     * @param list 要分组的集合
     * @param function 根据此方法进行分组
     * @param <K> 分组字段的泛型
     * @param <V> 集合泛型
     * @return 分组后的数据，如何集合为空将返回空集合
     */
    public static <K,V> Map<K, List<V>> groupingBy(List<V> list, Function<V, K> function){
        if (list == null) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.groupingBy(function));
    }


}
