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);
}
}