【Java】StreamFactory

Java Lambda Stream Factory

import java.util.*;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.*;

/**
 * 统一 Stream 工厂。
 * <p>将分散的 Stream 生成入口集中收拢,提供扁平、一致的 API。
 * <p>
 * <b>使用原则:</b>
 * <ul>
 *   <li><b>空指针安全:</b>
 *       <ul>
 *         <li>入参确定非空时,使用 {@code of(...)},为 null 会快速失败抛出 NPE。</li>
 *         <li>入参可能为空时,使用 {@code ofNullable(...)},为 null 时返回空流。</li>
 *       </ul>
 *   </li>
 *   <li><b>资源管理:</b>
 *       <ul>
 *         <li>对于纯内存数据源(Collection, 数组等),使用常规方法即可。</li>
 *         <li>对于持有资源的数据源(文件流, DB连接等),<b>必须</b>使用带 {@code closeHandler} 参数的方法,
 *             并配合 {@code try-with-resources} 语法块,以防短路操作导致资源泄漏。</li>
 *       </ul>
 *   </li>
 * </ul>
 */
public interface StreamFactory {

    // ====================== 空流 ======================

    /**
     * 返回一个空的顺序对象流。
     *
     * @param <T> 流元素类型
     * @return 空流
     */
    static <T> Stream<T> empty() {
        return Stream.empty();
    }

    // ====================== 对象 ======================

    /**
     * 将单个对象包装为顺序流。
     *
     * @param t   源对象,不允许为 {@code null}
     * @param <T> 元素类型
     * @return 包含单个元素的流
     * @throws NullPointerException 入参 {@code t} 为 {@code null} 时抛出
     */
    static <T> Stream<T> of(T t) {
        return Stream.of(t);
    }

    /**
     * 空安全地将单个对象包装为顺序流。
     *
     * @param t   源对象,允许为 {@code null}
     * @param <T> 元素类型
     * @return 非空时返回包含该元素的流;为 {@code null} 时返回空流
     */
    static <T> Stream<T> ofNullable(T t) {
        return t == null ? Stream.empty() : Stream.of(t);
    }

    // ====================== 对象数组 / 可变参数 ======================

    /**
     * 将可变参数数组转换为顺序流。
     *
     * @param values 源数组,不允许为 {@code null}
     * @param <T>    元素类型
     * @return 数组元素流
     * @throws NullPointerException 入参 {@code values} 为 {@code null} 时抛出
     */
    @SafeVarargs
    static <T> Stream<T> of(T... values) {
        Objects.requireNonNull(values);
        return Arrays.stream(values);
    }

    /**
     * 空安全地将可变参数数组转换为顺序流。
     *
     * @param values 源数组,允许为 {@code null}
     * @param <T>    元素类型
     * @return 非空时返回数组元素流;为 {@code null} 时返回空流
     */
    @SafeVarargs
    static <T> Stream<T> ofNullable(T... values) {
        return values == null ? Stream.empty() : Arrays.stream(values);
    }

    /**
     * 将对象数组的指定区间转换为顺序流。
     *
     * @param array          源数组,不允许为 {@code null}
     * @param startInclusive 起始下标(包含)
     * @param endExclusive   结束下标(不包含)
     * @param <T>            元素类型
     * @return 指定区间的元素流
     * @throws NullPointerException     数组为 {@code null} 时抛出
     * @throws IllegalArgumentException 区间下标越界或起始大于结束时抛出
     */
    static <T> Stream<T> of(T[] array, int startInclusive, int endExclusive) {
        Objects.requireNonNull(array);
        return Arrays.stream(array, startInclusive, endExclusive);
    }

    /**
     * 空安全地将对象数组的指定区间转换为顺序流。
     *
     * @param array          源数组,允许为 {@code null}
     * @param startInclusive 起始下标(包含)
     * @param endExclusive   结束下标(不包含)
     * @param <T>            元素类型
     * @return 数组非空时返回指定区间的元素流;数组为 {@code null} 时返回空流
     * @throws IllegalArgumentException 数组非空且区间下标非法时抛出
     */
    static <T> Stream<T> ofNullable(T[] array, int startInclusive, int endExclusive) {
        return array == null ? Stream.empty() : of(array, startInclusive, endExclusive);
    }

    // ====================== 集合 / Map ======================

    /**
     * 将 Collection 转换为顺序流。
     *
     * @param collection 源集合,不允许为 {@code null}
     * @param <T>        元素类型
     * @return 集合元素流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <T> Stream<T> of(Collection<T> collection) {
        Objects.requireNonNull(collection);
        return collection.stream();
    }

    /**
     * 空安全地将 Collection 转换为顺序流。
     *
     * @param collection 源集合,允许为 {@code null}
     * @param <T>        元素类型
     * @return 非空时返回集合元素流;为 {@code null} 时返回空流
     */
    static <T> Stream<T> ofNullable(Collection<T> collection) {
        return collection == null ? Stream.empty() : collection.stream();
    }

    /**
     * 将 Map 转换为 Entry 顺序流。
     *
     * @param map 源 Map,不允许为 {@code null}
     * @param <K> 键类型
     * @param <V> 值类型
     * @return Map.Entry 元素流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <K, V> Stream<Map.Entry<K, V>> of(Map<K, V> map) {
        Objects.requireNonNull(map);
        return map.entrySet().stream();
    }

    /**
     * 空安全地将 Map 转换为 Entry 顺序流。
     *
     * @param map 源 Map,允许为 {@code null}
     * @param <K> 键类型
     * @param <V> 值类型
     * @return 非空时返回 Map.Entry 元素流;为 {@code null} 时返回空流
     */
    static <K, V> Stream<Map.Entry<K, V>> ofNullable(Map<K, V> map) {
        return map == null ? Stream.empty() : map.entrySet().stream();
    }

    /**
     * 将 Map.keySet() 转换为顺序流。
     *
     * @param map 源 Map,不允许为 {@code null}
     * @param <K> 键类型
     * @param <V> 值类型
     * @return Map.keySet() 元素流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <K, V> Stream<K> ofKeys(Map<K, V> map) {
        Objects.requireNonNull(map);
        return map.keySet().stream();
    }

    /**
     * 空安全地将 Map.keySet() 转换为顺序流。
     *
     * @param map 源 Map,允许为 {@code null}
     * @param <K> 键类型
     * @param <V> 值类型
     * @return 非空时返回 Map.keySet() 元素流;为 {@code null} 时返回空流
     */
    static <K, V> Stream<K> ofNullableKeys(Map<K, V> map) {
        return map == null ? Stream.empty() : map.keySet().stream();
    }

    /**
     * 将 Map.values() 转换为顺序流。
     *
     * @param map 源 Map,不允许为 {@code null}
     * @param <K> 键类型
     * @param <V> 值类型
     * @return Map.values() 元素流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <K, V> Stream<V> ofValues(Map<K, V> map) {
        Objects.requireNonNull(map);
        return map.values().stream();
    }

    /**
     * 空安全地将 Map.values() 转换为顺序流。
     *
     * @param map 源 Map,允许为 {@code null}
     * @param <K> 键类型
     * @param <V> 值类型
     * @return 非空时返回 Map.values() 元素流;为 {@code null} 时返回空流
     */
    static <K, V> Stream<V> ofNullableValues(Map<K, V> map) {
        return map == null ? Stream.empty() : map.values().stream();
    }

    // ====================== Iterable / Iterator / Enumeration ======================

    /**
     * 将 Iterable 转换为顺序流。
     * <p><b>警告:</b>此方法返回的 Stream 不会自动管理底层数据源的生命周期。
     * 如果 Iterable 背后持有资源(如文件、数据库连接),且您计划使用短路操作
     * (如 limit, findFirst),请务必使用 {@link #of(Iterable, Runnable)} 方法
     * 并配合 try-with-resources 语句块使用,以防止资源泄漏。
     *
     * @param iterable 源可迭代对象,不允许为 {@code null}
     * @param <T>      元素类型
     * @return 对应元素流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <T> Stream<T> of(Iterable<T> iterable) {
        Objects.requireNonNull(iterable);
        return StreamSupport.stream(iterable.spliterator(), false);
    }

    /**
     * 将 Iterable 转换为顺序流, 并绑定关闭回调。当 Stream 关闭时,会执行 closeHandler。
     * <p><b>注意:</b>使用方必须通过 try-with-resources 或手动调用 close() 来触发回调。
     *
     * @param iterable     源可迭代对象,不允许为 {@code null}
     * @param closeHandler 关闭回调
     * @param <T>          元素类型
     * @return 对应元素流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <T> Stream<T> of(Iterable<T> iterable, Runnable closeHandler) {
        Objects.requireNonNull(iterable);
        Objects.requireNonNull(closeHandler);
        return StreamSupport.stream(iterable.spliterator(), false)
                .onClose(closeHandler);
    }

    /**
     * 空安全地将 Iterable 转换为顺序流。
     *
     * @param iterable 源可迭代对象,允许为 {@code null}
     * @param <T>      元素类型
     * @return 非空时返回对应元素流;为 {@code null} 时返回空流
     */
    static <T> Stream<T> ofNullable(Iterable<T> iterable) {
        return iterable == null ? Stream.empty() : of(iterable);
    }

    /**
     * 将 Iterator 转换为有序顺序流。
     * <p><b>警告:</b>此方法返回的 Stream 不会自动管理底层数据源的生命周期。
     * 如果 Iterator 背后持有资源(如文件、数据库连接),且您计划使用短路操作
     * (如 limit, findFirst),请务必使用 {@link #of(Iterator, Runnable)} 方法
     * 并配合 try-with-resources 语句块使用,以防止资源泄漏。
     *
     * @param iterator 源迭代器,不允许为 {@code null}
     * @param <T>      元素类型
     * @return 对应元素流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <T> Stream<T> of(Iterator<T> iterator) {
        Objects.requireNonNull(iterator);
        return StreamSupport.stream(
                Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false);
    }

    /**
     * 将 Iterator 转换为有序顺序流, 并绑定关闭回调。当 Stream 关闭时,会执行 closeHandler。
     * <p><b>注意:</b>使用方必须通过 try-with-resources 或手动调用 close() 来触发回调。
     *
     * @param iterator     源迭代器,不允许为 {@code null}
     * @param closeHandler 关闭回调
     * @param <T>          元素类型
     * @return 对应元素流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <T> Stream<T> of(Iterator<T> iterator, Runnable closeHandler) {
        Objects.requireNonNull(iterator);
        Objects.requireNonNull(closeHandler);
        return StreamSupport.stream(
                Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED),
                false
        ).onClose(closeHandler);
    }

    /**
     * 空安全地将 Iterator 转换为有序顺序流。
     *
     * @param iterator 源迭代器,允许为 {@code null}
     * @param <T>      元素类型
     * @return 非空时返回对应元素流;为 {@code null} 时返回空流
     */
    static <T> Stream<T> ofNullable(Iterator<T> iterator) {
        return iterator == null ? Stream.empty() : of(iterator);
    }

    /**
     * 将 Enumeration 转换为有序顺序流。
     * <p>兼容遗留 API(如 Properties、Servlet API 等),保持遍历顺序。
     * <p><b>警告:</b>此方法返回的 Stream 不会自动管理底层数据源的生命周期。
     * 如果 Enumeration 背后持有资源(如文件、数据库连接),且您计划使用短路操作
     * (如 limit, findFirst),请务必使用 {@link #of(Enumeration, Runnable)} 方法
     * 并配合 try-with-resources 语句块使用,以防止资源泄漏。
     *
     * @param enumeration 源枚举对象,不允许为 {@code null}
     * @param <T>         元素类型
     * @return 对应元素流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <T> Stream<T> of(Enumeration<T> enumeration) {
        Objects.requireNonNull(enumeration);
        return of(new Iterator<T>() {
            @Override
            public boolean hasNext() {
                return enumeration.hasMoreElements();
            }

            @Override
            public T next() {
                return enumeration.nextElement();
            }
        });
    }

    /**
     * 将 Enumeration 转换为有序顺序流, 并绑定关闭回调。当 Stream 关闭时,会执行 closeHandler。
     * <p>兼容遗留 API(如 Properties、Servlet API 等),保持遍历顺序。
     * <p><b>注意:</b>使用方必须通过 try-with-resources 或手动调用 close() 来触发回调。
     *
     * @param enumeration  源枚举对象,不允许为 {@code null}
     * @param closeHandler 关闭回调
     * @param <T>          元素类型
     * @return 对应元素流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <T> Stream<T> of(Enumeration<T> enumeration, Runnable closeHandler) {
        Objects.requireNonNull(enumeration);
        Objects.requireNonNull(closeHandler);
        // 复用 Iterator 的实现
        return of(new Iterator<T>() {
            @Override
            public boolean hasNext() {
                return enumeration.hasMoreElements();
            }

            @Override
            public T next() {
                return enumeration.nextElement();
            }
        }, closeHandler);
    }

    /**
     * 空安全地将 Enumeration 转换为有序顺序流。
     *
     * @param enumeration 源枚举对象,允许为 {@code null}
     * @param <T>         元素类型
     * @return 非空时返回对应元素流;为 {@code null} 时返回空流
     */
    static <T> Stream<T> ofNullable(Enumeration<T> enumeration) {
        return enumeration == null ? Stream.empty() : of(enumeration);
    }

    // ====================== 基础类型数组 (int) ======================

    /**
     * 将 int 数组转换为 IntStream。
     *
     * @param array 源数组,不允许为 {@code null}
     * @return 对应 IntStream
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static IntStream of(int[] array) {
        Objects.requireNonNull(array);
        return Arrays.stream(array);
    }

    /**
     * 空安全地将 int 数组转换为 IntStream。
     *
     * @param array 源数组,允许为 {@code null}
     * @return 非空时返回对应 IntStream;为 {@code null} 时返回空流
     */
    static IntStream ofNullable(int[] array) {
        return array == null ? IntStream.empty() : of(array);
    }

    /**
     * 将 int 数组的指定区间转换为 IntStream。
     *
     * @param array          源数组,不允许为 {@code null}
     * @param startInclusive 起始下标(包含)
     * @param endExclusive   结束下标(不包含)
     * @return 指定区间的 IntStream
     * @throws NullPointerException     数组为 {@code null} 时抛出
     * @throws IllegalArgumentException 区间下标非法时抛出
     */
    static IntStream of(int[] array, int startInclusive, int endExclusive) {
        Objects.requireNonNull(array);
        return Arrays.stream(array, startInclusive, endExclusive);
    }

    /**
     * 空安全地将 int 数组的指定区间转换为 IntStream。
     *
     * @param array          源数组,允许为 {@code null}
     * @param startInclusive 起始下标(包含)
     * @param endExclusive   结束下标(不包含)
     * @return 数组非空时返回指定区间的 IntStream;数组为 {@code null} 时返回空流
     * @throws IllegalArgumentException 数组非空且区间下标非法时抛出
     */
    static IntStream ofNullable(int[] array, int startInclusive, int endExclusive) {
        return array == null ? IntStream.empty() : of(array, startInclusive, endExclusive);
    }

    // ====================== 基础类型数组 (long)  ======================

    /**
     * 将 long 数组转换为 LongStream。
     *
     * @param array 源数组,不允许为 {@code null}
     * @return 对应 LongStream
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static LongStream of(long[] array) {
        Objects.requireNonNull(array);
        return Arrays.stream(array);
    }

    /**
     * 空安全地将 long 数组转换为 LongStream。
     *
     * @param array 源数组,允许为 {@code null}
     * @return 非空时返回对应 LongStream;为 {@code null} 时返回空流
     */
    static LongStream ofNullable(long[] array) {
        return array == null ? LongStream.empty() : of(array);
    }

    /**
     * 将 long 数组的指定区间转换为 LongStream。
     *
     * @param array          源数组,不允许为 {@code null}
     * @param startInclusive 起始下标(包含)
     * @param endExclusive   结束下标(不包含)
     * @return 指定区间的 LongStream
     * @throws NullPointerException     数组为 {@code null} 时抛出
     * @throws IllegalArgumentException 区间下标非法时抛出
     */
    static LongStream of(long[] array, int startInclusive, int endExclusive) {
        Objects.requireNonNull(array);
        return Arrays.stream(array, startInclusive, endExclusive);
    }

    /**
     * 空安全地将 long 数组的指定区间转换为 LongStream。
     *
     * @param array          源数组,允许为 {@code null}
     * @param startInclusive 起始下标(包含)
     * @param endExclusive   结束下标(不包含)
     * @return 数组非空时返回指定区间的 LongStream;数组为 {@code null} 时返回空流
     * @throws IllegalArgumentException 数组非空且区间下标非法时抛出
     */
    static LongStream ofNullable(long[] array, int startInclusive, int endExclusive) {
        return array == null ? LongStream.empty() : of(array, startInclusive, endExclusive);
    }

    // ====================== 基础类型数组 (double)  ======================

    /**
     * 将 double 数组转换为 DoubleStream。
     *
     * @param array 源数组,不允许为 {@code null}
     * @return 对应 DoubleStream
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static DoubleStream of(double[] array) {
        Objects.requireNonNull(array);
        return Arrays.stream(array);
    }

    /**
     * 空安全地将 double 数组转换为 DoubleStream。
     *
     * @param array 源数组,允许为 {@code null}
     * @return 非空时返回对应 DoubleStream;为 {@code null} 时返回空流
     */
    static DoubleStream ofNullable(double[] array) {
        return array == null ? DoubleStream.empty() : of(array);
    }

    /**
     * 将 double 数组的指定区间转换为 DoubleStream。
     *
     * @param array          源数组,不允许为 {@code null}
     * @param startInclusive 起始下标(包含)
     * @param endExclusive   结束下标(不包含)
     * @return 指定区间的 DoubleStream
     * @throws NullPointerException     数组为 {@code null} 时抛出
     * @throws IllegalArgumentException 区间下标非法时抛出
     */
    static DoubleStream of(double[] array, int startInclusive, int endExclusive) {
        Objects.requireNonNull(array);
        return Arrays.stream(array, startInclusive, endExclusive);
    }

    /**
     * 空安全地将 double 数组的指定区间转换为 DoubleStream。
     *
     * @param array          源数组,允许为 {@code null}
     * @param startInclusive 起始下标(包含)
     * @param endExclusive   结束下标(不包含)
     * @return 数组非空时返回指定区间的 DoubleStream;数组为 {@code null} 时返回空流
     * @throws IllegalArgumentException 数组非空且区间下标非法时抛出
     */
    static DoubleStream ofNullable(double[] array, int startInclusive, int endExclusive) {
        return array == null ? DoubleStream.empty() : of(array, startInclusive, endExclusive);
    }

    // ====================== Spliterator ======================

    /**
     * 基于 Spliterator 创建对象流,可指定是否并行。
     *
     * @param spliterator 源 Spliterator,不允许为 {@code null}
     * @param parallel    {@code true} 创建并行流,{@code false} 创建串行流
     * @param <T>         元素类型
     * @return 对应对象流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <T> Stream<T> of(Spliterator<T> spliterator, boolean parallel) {
        Objects.requireNonNull(spliterator);
        return StreamSupport.stream(spliterator, parallel);
    }

    /**
     * 基于 Spliterator 创建 IntStream,可指定是否并行。
     *
     * @param spliterator 源 Spliterator,不允许为 {@code null}
     * @param parallel    {@code true} 创建并行流,{@code false} 创建串行流
     * @return 对应 IntStream
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static IntStream of(Spliterator.OfInt spliterator, boolean parallel) {
        Objects.requireNonNull(spliterator);
        return StreamSupport.intStream(spliterator, parallel);
    }

    /**
     * 基于 Spliterator 创建 LongStream,可指定是否并行。
     *
     * @param spliterator 源 Spliterator,不允许为 {@code null}
     * @param parallel    {@code true} 创建并行流,{@code false} 创建串行流
     * @return 对应 LongStream
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static LongStream of(Spliterator.OfLong spliterator, boolean parallel) {
        Objects.requireNonNull(spliterator);
        return StreamSupport.longStream(spliterator, parallel);
    }

    /**
     * 基于 Spliterator 创建 DoubleStream,可指定是否并行。
     *
     * @param spliterator 源 Spliterator,不允许为 {@code null}
     * @param parallel    {@code true} 创建并行流,{@code false} 创建串行流
     * @return 对应 DoubleStream
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static DoubleStream of(Spliterator.OfDouble spliterator, boolean parallel) {
        Objects.requireNonNull(spliterator);
        return StreamSupport.doubleStream(spliterator, parallel);
    }

    // ====================== 生成与迭代 ======================

    /**
     * 返回一个无限顺序流,每个元素由提供的 Supplier 生成。
     * <p>等同于 {@code Stream.generate(supplier)},但增加了非空校验。
     *
     * @param supplier 元素生成器,不允许为 {@code null}
     * @param <T>      元素类型
     * @return 无限顺序流
     * @throws NullPointerException 入参为 {@code null} 时抛出
     */
    static <T> Stream<T> generate(Supplier<T> supplier) {
        Objects.requireNonNull(supplier);
        return Stream.generate(supplier);
    }

    /**
     * 返回一个无限顺序流,由初始元素和迭代函数生成。
     * <p>等同于 {@code Stream.iterate(seed, f)}。
     *
     * @param seed 初始元素
     * @param f    迭代函数,不允许为 {@code null}
     * @param <T>  元素类型
     * @return 无限顺序流
     * @throws NullPointerException 迭代函数为 {@code null} 时抛出
     */
    static <T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
        Objects.requireNonNull(f);
        return Stream.iterate(seed, f);
    }
}
posted @ 2022-08-25 15:43  XKIND  阅读(63)  评论(0)    收藏  举报