APS 项目中java常用stream方法

StreamUtils 是一个 Java Stream API 增强工具类,主要提供三类线程安全的集合操作方法:1) 支持 null 键的 Map 收集器(使用 LinkedHashMap 保持顺序),解决传统 toMap() 的 NPE 问题;2) 类型安全的列表转换方法,可选择生成可变或不可变列表;3) 列表转集合的自动去重功能。工具类采用静态方法设计,所有方法均可直接调用,特别解决了 Stream API 中常见的空指针和集合转换问题。其中 toMapWithNullKeys() 方法允许 null 

package com.olivia.sdk.utils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * StreamUtils - Java Stream API增强工具类
 * 
 * 该工具类提供了一系列用于简化集合操作的静态方法,主要包括:
 * 1. 支持null键的Map收集器
 * 2. 列表与集合的类型转换工具
 * 3. 不可变集合与可变集合的安全转换
 * 
 * 所有方法均为线程安全的静态方法,可直接通过类名调用。
 * 设计目标是解决Java Stream API中常见的空指针问题和不可变集合转换问题。
 */
public class StreamUtils {

    /**
     * 将列表转换为Map,允许键为null值
     * 
     * 与Collectors.toMap()不同,本方法不会在遇到null键时抛出NPE,
     * 而是将null作为合法的键存入Map中。
     * 
     * 注意:若列表中存在多个元素生成相同的键(包括null键),
     * 后一个元素的值将覆盖前一个元素的值。
     * 
     * @param <T>         列表元素类型
     * @param <K>         Map键的类型
     * @param <U>         Map值的类型
     * @param list        待转换的列表
     * @param keyMapper   键映射函数
     * @param valueMapper 值映射函数
     * @return 包含所有元素映射的LinkedHashMap(保持元素原始顺序)
     */
    public static <T, K, U> Map<K, U> toMapWithNullKeys(List<T> list, Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) {
        return list.stream().collect(toMapWithNullKeys(keyMapper, valueMapper));
    }

    /**
     * 创建一个支持null键的Map收集器
     * 
     * 该收集器生成的Map实现为LinkedHashMap,能够保持元素的插入顺序。
     * 适用于需要处理可能包含null键的流操作场景。
     * 
     * @param <T>         流元素类型
     * @param <K>         Map键的类型
     * @param <U>         Map值的类型
     * @param keyMapper   键映射函数
     * @param valueMapper 值映射函数
     * @return 支持null键的Map收集器
     */
    public static <T, K, U> Collector<T, ?, Map<K, U>> toMapWithNullKeys(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) {
        return Collector.of(
            LinkedHashMap::new, // 使用LinkedHashMap保持插入顺序
            (map, element) -> {
                K key = keyMapper.apply(element);
                U value = valueMapper.apply(element);
                map.put(key, value); // 直接允许null键
            },
            (left, right) -> {
                left.putAll(right); // 合并时后添加的元素覆盖已有元素
                return left;
            },
            Collector.Characteristics.IDENTITY_FINISH // 标识收集器的完成函数为恒等函数
        );
    }

    /**
     * 将一个列表转换为另一种类型的列表
     * 
     * 该方法会生成一个不可变的列表,若需要可变列表,请使用重载方法并传入true参数。
     * 
     * @param <I>    输入列表元素类型
     * @param <R>    输出列表元素类型
     * @param list   输入列表
     * @param mapper 元素转换函数
     * @return 转换后的不可变列表
     */
    public static <I, R> List<R> list2List(List<I> list, Function<I, R> mapper) {
        return list2List(list, mapper, false);
    }

    /**
     * 将一个列表转换为另一种类型的列表,并可选择是否生成可变列表
     * 
     * @param <I>        输入列表元素类型
     * @param <R>        输出列表元素类型
     * @param list       输入列表
     * @param mapper     元素转换函数
     * @param canModify  是否需要生成可变列表
     * @return 转换后的列表(根据参数决定是否可变)
     */
    public static <I, R> List<R> list2List(List<I> list, Function<I, R> mapper, boolean canModify) {
        List<R> tl = list.stream().map(mapper).toList(); // Java 16+ 的toList()生成不可变列表
        if (canModify) {
            return new ArrayList<>(tl); // 包装为可变ArrayList
        }
        return tl; // 直接返回不可变列表
    }

    /**
     * 将列表转换为集合,自动去重
     * 
     * 该方法使用Collectors.toSet()生成集合,因此不保证元素顺序。
     * 若需要有序集合,请使用Collectors.toCollection(LinkedHashSet::new)。
     * 
     * @param <I>    输入列表元素类型
     * @param <R>    输出集合元素类型
     * @param list   输入列表
     * @param mapper 元素转换函数
     * @return 转换后的集合(无序,可能已去重)
     */
    public static <I, R> Set<R> list2set(List<I> list, Function<I, R> mapper) {
        return list.stream().map(mapper).collect(Collectors.toSet());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值