Stream流式编程工具类,开发必备
把自己写的流式编程工具分享出来,不涉及公司业务,非常便捷,不用在业务层看到一条龙式的Stream代码了;
大家用的最多的应该是转list,转set,以及setVFromE;
觉得好用点个赞就行
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
/**
 * @desc Stream流处理工具
 */
public class StreamUtils {
    /**
     * 转换map,获取本身,去重,对象、key忽略null
     * @param source 集合
     * @param keyFunction 获取key函数
     * @return
     */
    public static <T,K> Map<K,T> toMap(Collection<T> source, Function<T,K> keyFunction){
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream().filter(Objects::nonNull).filter(obj -> Objects.nonNull(keyFunction.apply(obj)))
                .collect(Collectors.toMap(keyFunction, Function.identity(), (v1, v2) -> v2));
    }
    /**
     * 转换map,获取本身,去重,对象、key忽略null
     * @param source 集合
     * @param keyFunction 获取key函数
     * @param predicate 过滤条件
     * @return
     */
    public static <T,K> Map<K,T> toMap(Collection<T> source, Function<T,K> keyFunction, Predicate<? super T> predicate){
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream().filter(Objects::nonNull).filter(obj -> Objects.nonNull(keyFunction.apply(obj))).filter(predicate)
                .collect(Collectors.toMap(keyFunction, Function.identity(), (v1, v2) -> v2));
    }
    /**
     * 转换map,去重,对象、key、value忽略null
     * @param source 集合
     * @param keyFunction 获取key函数
     * @param valueFunction 获取值函数
     * @return
     */
    public static <T, K, V> Map<K, V> toMap(Collection<T> source, Function<T, K> keyFunction, Function<T, V> valueFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream().filter(Objects::nonNull).filter(obj -> Objects.nonNull(keyFunction.apply(obj)))
                .filter(obj -> Objects.nonNull(valueFunction.apply(obj)))
                .collect(Collectors.toMap(keyFunction, valueFunction, (v1, v2) -> v2));
    }
    /**
     * 转换map,去重,对象、key、value忽略null
     * @param source 集合
     * @param keyFunction 获取key函数
     * @param valueFunction 获取值函数
     * @param mergeFunction 合并方式
     * @return
     */
    public static <T, K, V> Map<K, V> toMap(Collection<T> source, Function<T, K> keyFunction, Function<T, V> valueFunction, BinaryOperator<V> mergeFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream().filter(Objects::nonNull).filter(obj -> Objects.nonNull(keyFunction.apply(obj)))
                .filter(obj -> Objects.nonNull(valueFunction.apply(obj))).collect(
                Collectors.toMap(keyFunction, valueFunction, mergeFunction));
    }
    /**
     * 转换map,去重,使用map重新put方式
     * @param source 集合
     * @param keyFunction 获取key函数
     * @param valueFunction 获取值函数
     * @return
     */
    public static <T, K, V> HashMap<K, V> toMap2(Collection<T> source, Function<T, K> keyFunction, Function<T, V> valueFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream().filter(Objects::nonNull).filter(obj -> Objects.nonNull(keyFunction.apply(obj))).collect(
                HashMap<K, V>::new,
                (m, v) -> m.put(keyFunction.apply(v), valueFunction.apply(v)),
                HashMap<K, V>::putAll);
    }
    public static <T, R> List<R> toList(Collection<T> source, Function<T, R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream().filter(Objects::nonNull).map(function)
                .collect(Collectors.toList());
    }
    public static <T, R> List<R> toListIgnoreNull(Collection<T> source, Function<T, R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream().filter(Objects::nonNull).map(function).filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
    public static <T,R> Set<R> toSet(Collection<T> source, Function<T,R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newHashSet();
        }
        return source.stream().filter(Objects::nonNull).map(function)
                .collect(Collectors.toSet());
    }
    public static <T,R> Set<R> toSetIgnoreNull(Collection<T> source, Function<T,R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newHashSet();
        }
        return source.stream().filter(Objects::nonNull).map(function).filter(Objects::nonNull)
                .collect(Collectors.toSet());
    }
    public static <T,R> LinkedHashSet<R> toLinkedHashSet(Collection<T> source, Function<T,R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return new LinkedHashSet<R>();
        }
        return source.stream().filter(Objects::nonNull).map(function).filter(Objects::nonNull)
                .collect(Collectors.toCollection(LinkedHashSet::new));
    }
    public static <T,R> LinkedList<R> toLinkedList(Collection<T> source, Function<T,R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newLinkedList();
        }
        return source.stream().filter(Objects::nonNull).map(function).filter(Objects::nonNull)
                .collect(Collectors.toCollection(LinkedList::new));
    }
    /**
     * 将集合分组,遇到重复的key,value放入集合中
     * @param source
     * @param keyFunction
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K,V> Map<K,List<V>> groupToMap(Collection<V> source,Function<? super V, ? extends K> keyFunction){
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream().filter(Objects::nonNull).filter(s -> Objects.nonNull(keyFunction.apply(s)))
                .collect(Collectors.groupingBy(keyFunction));
    }
    /**
     * 将集合分组,遇到重复的key,value放入集合中
     * @param source
     * @param keyFunction
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K,V> LinkedHashMap<K,List<V>> groupToLinkedHashMap(Collection<V> source,Function<? super V, ? extends K> keyFunction){
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newLinkedHashMap();
        }
        return source.stream().filter(Objects::nonNull).filter(s -> Objects.nonNull(keyFunction.apply(s)))
                .collect(Collectors.groupingBy(keyFunction, LinkedHashMap::new, Collectors.toList()));
    }
    /**
     * 将集合分组,遇到重复的key,并统计重复key的次数
     * @param source
     * @param keyFunction
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K,V> Map<K,Long> groupToMapCount(Collection<V> source,Function<? super V, ? extends K> keyFunction){
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream().filter(Objects::nonNull).filter(s -> Objects.nonNull(keyFunction.apply(s)))
                .collect(Collectors.groupingBy(keyFunction,Collectors.counting()));
    }
    public static <T> List<T> filter(Collection<T> source,Predicate<? super T> predicate){
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream().filter(predicate).collect(Collectors.toList());
    }
    public static <T> Set<T> filter(Set<T> set,Predicate<? super T> predicate){
        if (CollectionUtils.isEmpty(set)) {
            return Sets.newHashSet();
        }
        return set.stream().filter(predicate).collect(Collectors.toCollection(HashSet::new));
    }
    public static <T> LinkedHashSet<T> filterToSet(Collection<T> source,Predicate<? super T> predicate){
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newLinkedHashSet();
        }
        return source.stream().filter(predicate).collect(Collectors.toCollection(LinkedHashSet::new));
    }
    public static <T> Stream<T> filterStream(Collection<T> source, Predicate<? super T> predicate){
        if (CollectionUtils.isEmpty(source)) {
            return Stream.empty();
        }
        return source.stream().filter(predicate);
    }
    public static <T> Stream<T> filterStream(Collection<T> source, Predicate<? super T> predicate1, Predicate<? super T> predicate2){
        if (CollectionUtils.isEmpty(source)) {
            return Stream.empty();
        }
        return source.stream().filter(predicate1).filter(predicate2);
    }
    public static <T,R> List<R> filterMapList(Collection<T> source, Predicate<? super T> predicate, Function<T , R> mapFunction){
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream().filter(predicate).map(mapFunction).collect(Collectors.toList());
    }
    public static <T,R> List<R> filterMapList(Collection<T> source, Predicate<? super T> predicate1, Predicate<? super T> predicate2, Function<T , R> mapFunction){
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream().filter(predicate1).filter(predicate2).map(mapFunction).collect(Collectors.toList());
    }
    public static <T,R> Set<R> filterMapSet(Collection<T> source, Predicate<? super T> predicate, Function<T , R> mapFunction){
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newHashSet();
        }
        return source.stream().filter(predicate).map(mapFunction).collect(Collectors.toSet());
    }
    public static <T,R> Set<R> filterMapSet(Collection<T> source, Predicate<? super T> predicate1,Predicate<? super T> predicate2, Function<T , R> mapFunction){
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newHashSet();
        }
        return source.stream().filter(predicate1).filter(predicate2).map(mapFunction).collect(Collectors.toSet());
    }
    /**
     * 从eList中设置字段值到vList中
     * @param vList vList v对象集合
     * @param eList eList e对象集合
     * @param keyFunctionE e对象获取key方法
     * @param keyFunctionV v对象获取key方法
     * @param consumer 赋值转换方法
     */
    public static <V,E,R> void setVFromE(Collection<V> vList, Collection<E> eList, Function<E,R> keyFunctionE,
                                              Function<V,R> keyFunctionV,
                                              BiConsumer<V,E> consumer){
        if (CollectionUtils.isNotEmpty(eList)) {
            Map<R, E> map = StreamUtils.toMap(eList,keyFunctionE);
            vList.stream().filter(Objects::nonNull).forEach(v -> {
                E e = map.get(keyFunctionV.apply(v));
                if (Objects.nonNull(e)) {
                    consumer.accept(v,e);
                }
            });
        }
    }
    /**
     * 从eList中设置集合项字段值到vList中的集合项属性
     * @param vList vList v对象集合
     * @param eList eList e对象集合
     * @param keyFunctionE e对象获取key方法
     * @param keyFunctionV v对象获取key方法
     * @param consumer 赋值转换方法
     */
    public static <V,E,R> void setVListFromE(Collection<V> vList, Collection<E> eList, Function<E,R> keyFunctionE,
                                         Function<V,R> keyFunctionV,
                                         BiConsumer<V,List<E>> consumer){
        if (CollectionUtils.isNotEmpty(eList)) {
            Map<R, List<E>> map = StreamUtils.groupToMap(eList,keyFunctionE);
            vList.stream().filter(Objects::nonNull).forEach(v -> {
                List<E> e = map.get(keyFunctionV.apply(v));
                if (Objects.nonNull(e)) {
                    consumer.accept(v,e);
                }
            });
        }
    }
    /**
     * 累加
     * @param source 原集合
     * @param valueFunction 获取BigDecimal字段
     * @param <T>
     * @return
     */
    public static <T> BigDecimal add(Collection<T> source, Function<T,BigDecimal> valueFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return BigDecimal.ZERO;
        }
        return source.stream().filter(Objects::nonNull).map(valueFunction)
                .reduce(BigDecimal.ZERO,BigDecimal::add);
    }
    /**
     * 累加并设置四舍五入(保留newScale位小数)
     * @param source 原集合
     * @param valueFunction 获取BigDecimal字段
     * @param newScale 小数位数
     * @param <T>
     * @return
     */
    public static <T> BigDecimal addHalfUp(Collection<T> source, Function<T,BigDecimal> valueFunction,int newScale) {
        if (CollectionUtils.isEmpty(source)) {
            return BigDecimal.ZERO;
        }
        return source.stream().filter(Objects::nonNull).map(valueFunction)
                .reduce(BigDecimal.ZERO,BigDecimal::add).setScale(newScale, RoundingMode.HALF_UP);
    }
    /**
     * 累加并设置四舍五入(保留2位小数)
     * @param source 原集合
     * @param valueFunction 获取BigDecimal字段
     * @param <T>
     * @return
     */
    public static <T> BigDecimal addHalfUp(Collection<T> source, Function<T,BigDecimal> valueFunction) {
       return addHalfUp(source, valueFunction,2);
    }
    public static <T,K> Predicate<T> distinctByKey(Function<? super T, K> keyExtractor) {
        Set<K> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }
    public static <T,K> List<T> distinctByKey(List<T> list, Function<? super T, K> keyExtractor) {
        return list.stream().filter(distinctByKey(keyExtractor)).collect(Collectors.toList());
    }
}
Stream流式编程工具类,开发必备的更多相关文章
- Stream流式编程
		Stream流式编程 Stream流 说到Stream便容易想到I/O Stream,而实际上,谁规定“流”就一定是“IO流”呢?在Java 8中,得益于Lambda所带来的函数式编程,引入了一个 ... 
- 让代码变得优雅简洁的神器:Java8  Stream流式编程
		原创/朱季谦 本文主要基于实际项目常用的Stream Api流式处理总结. 因笔者主要从事风控反欺诈相关工作,故而此文使用比较熟悉的三要素之一的[手机号]黑名单作代码案例说明. 我在项目当中,很早就开 ... 
- stream流操作List工具类
		工作中操作List对于程序猿来说是"基本操作",为了更加便利,对JDK8的新特性stream流进行二次封装.话不多说,直接上代码 package com.mydemo; impor ... 
- Java8 新特性 —— Stream 流式编程
		本文部分摘自 On Java 8 流概述 集合优化了对象的存储,大多数情况下,我们将对象存储在集合是为了处理他们.使用流可以帮助我们处理对象,无需迭代集合中的元素,即可直接提取和操作元素,并添加了很多 ... 
- JDK8新特性(二) 流式编程Stream
		流式编程是1.8中的新特性,基于常用的四种函数式接口以及Lambda表达式对集合类数据进行类似流水线一般的操作 流式编程分为大概三个步骤:获取流 → 操作流 → 返回操作结果 流的获取方式 这里先了解 ... 
- java高并发系列 - 第15天:JUC中的Semaphore,最简单的限流工具类,必备技能
		这是java高并发系列第15篇文章 Semaphore(信号量)为多线程协作提供了更为强大的控制方法,前面的文章中我们学了synchronized和重入锁ReentrantLock,这2种锁一次都只能 ... 
- 第46天学习打卡(四大函数式接口 Stream流式计算 ForkJoin 异步回调 JMM Volatile)
		小结与扩展 池的最大的大小如何去设置! 了解:IO密集型,CPU密集型:(调优) //1.CPU密集型 几核就是几个线程 可以保持效率最高 //2.IO密集型判断你的程序中十分耗IO的线程,只要大于 ... 
- 万字详解 | Java 流式编程
		概述 Stream API 是 Java 中引入的一种新的数据处理方法.它提供了一种高效且易于使用的方法来处理数据集合.Stream API 支持函数式编程,可以让我们以简洁.优雅的方式进行数据操作, ... 
- 20190827 On Java8 第十四章 流式编程
		第十四章 流式编程 流的一个核心好处是,它使得程序更加短小并且更易理解.当 Lambda 表达式和方法引用(method references)和流一起使用的时候会让人感觉自成一体.流使得 Java ... 
- FTP工具类开发
		正所谓工欲善其事必先利其器,熟悉了下一套流程,以此铭记. 1.FTP服务搭建 由于本人使用wondiow系统,所以针对window的童鞋们可以查看.至于windowX这里配置类似,所以不要纠结于win ... 
随机推荐
- 认识soui4js(第3篇):使用C/C++开发扩展模块
			首先需要明确:JS代码本身不具备直接调用系统API的能力,JS代码能调用什么功能,都依赖于其它扩展模块提供了什么样的接口. soui4js模块将soui的界面能力作为一个js模块导出到了js中,使得j ... 
- Jenkins插件:Generic Webhook Trigger
			Jenkins插件:Generic Webhook Trigger 作为一名软件测试工程师,在日常工作中,我经常需要使用Jenkins来进行持续集成和持续部署(CI/CD).而Jenkins的众多插件 ... 
- 常用Maven命令
			一.常用命令 1.1 打包 mvn clean package -DskipTests 指定环境 mvn clean install -Dmaven.test.skip=true -Pprod-tx ... 
- Android开发之定时任务(AlarmManager、WorkManager)
			Android 程序的定时任务主要有AlarmManager.WorkManager两种. 一.AlarmManager AlarmManager,又称闹钟,可以设置一次性任务,周期重复任务,定时重复 ... 
- 手把手教你用 MicroPython 玩转幻尔串口舵机,代码+教程全公开
			原文链接: FreakStudio的博客 摘要 信号发生扩展板通过SPI接口生成可调频率和幅度的正弦波.方波和三角波,频率小于1MHz.支持幅度调节,提供原始和6倍放大输出接口.配备5阶低通滤波器.噪 ... 
- C/C++ 创建Socket实现双工通信
			点击查看代码 实现简单的Socket通信 服务端代码(Server) #include <stdio.h> #include <winsock2.h> #pragma comm ... 
- 自动化平台-环境搭建2-cmd 下mysql 卸载命令
			"" net stop mysql sc delete mysql rd /s /q "C:\Program Files\MySQL" rd /s /q &qu ... 
- TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
			\3c span id="mce_marker" data-mce-type="bookmark">\3c /span>\3c span id=&q ... 
- Git 命令使用体验的神器 -- tig
			tig, 就是把 Git 这个单词倒过来念, 它是一个命令行工具, 日常使用中我用它来取代 Git 最高频的几个操作, 如 git log, git diff 以及 git blame等, 使用常见安 ... 
- phpstorm、goland常用快捷键
			1) 文件操作相关的快捷键 快捷键 作用 Ctrl + E 打开最近浏览过的文件 Ctrl + N 快速打开某个 struct 结构体所在的文件 Ctrl + Shift + N 快速打开文件 Shi ... 
