mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add Stream utils
This commit is contained in:
parent
6a76d260fe
commit
b0e62df7c6
@ -3,7 +3,7 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.6.7 (2021-06-06)
|
||||
# 5.6.7 (2021-06-07)
|
||||
|
||||
### 🐣新特性
|
||||
* 【core 】 CharSequenceUtil增加join重载(issue#I3TFJ5@Gitee)
|
||||
@ -12,6 +12,7 @@
|
||||
* 【core 】 改进TreeUtil.buid算法性能(pr#1594@Github)
|
||||
* 【core 】 CsvConfig的setXXX返回this(issue#I3UIQF@Gitee)
|
||||
* 【all 】 增加jmh基准测试
|
||||
* 【core 】 增加StreamUtil和CollectorUtil
|
||||
|
||||
### 🐞Bug修复
|
||||
* 【core 】 修复FileUtil.normalize去掉末尾空格问题(issue#1603@Github)
|
||||
|
@ -0,0 +1,64 @@
|
||||
package cn.hutool.core.stream;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
/**
|
||||
* 可变的汇聚操作{@link Collector} 相关工具封装
|
||||
*
|
||||
* @author looly
|
||||
* @since 5.6.7
|
||||
*/
|
||||
public class CollectorUtil {
|
||||
|
||||
/**
|
||||
* 提供任意对象的Join操作的{@link Collector}实现,对象默认调用toString方法
|
||||
*
|
||||
* @param delimiter 分隔符
|
||||
* @param <T> 对象类型
|
||||
* @return {@link Collector}
|
||||
*/
|
||||
public static <T> Collector<T, ?, String> joining(CharSequence delimiter) {
|
||||
return joining(delimiter, Object::toString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供任意对象的Join操作的{@link Collector}实现
|
||||
*
|
||||
* @param delimiter 分隔符
|
||||
* @param toStringFunc 自定义指定对象转换为字符串的方法
|
||||
* @param <T> 对象类型
|
||||
* @return {@link Collector}
|
||||
*/
|
||||
public static <T> Collector<T, ?, String> joining(CharSequence delimiter,
|
||||
Function<T, ? extends CharSequence> toStringFunc) {
|
||||
return joining(delimiter, StrUtil.EMPTY, StrUtil.EMPTY, toStringFunc);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供任意对象的Join操作的{@link Collector}实现
|
||||
*
|
||||
* @param delimiter 分隔符
|
||||
* @param prefix 前缀
|
||||
* @param suffix 后缀
|
||||
* @param toStringFunc 自定义指定对象转换为字符串的方法
|
||||
* @param <T> 对象类型
|
||||
* @return {@link Collector}
|
||||
*/
|
||||
public static <T> Collector<T, ?, String> joining(CharSequence delimiter,
|
||||
CharSequence prefix,
|
||||
CharSequence suffix,
|
||||
Function<T, ? extends CharSequence> toStringFunc) {
|
||||
return new SimpleCollector<>(
|
||||
() -> new StringJoiner(delimiter, prefix, suffix),
|
||||
(joiner, ele) -> joiner.add(toStringFunc.apply(ele)),
|
||||
StringJoiner::merge,
|
||||
StringJoiner::toString,
|
||||
Collections.emptySet()
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package cn.hutool.core.stream;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
/**
|
||||
* 简单{@link Collector}接口实现
|
||||
*
|
||||
* @param <T> 输入数据类型
|
||||
* @param <A> 累积结果的容器类型
|
||||
* @param <R> 数据结果类型
|
||||
* @since 5.6.7
|
||||
*/
|
||||
public class SimpleCollector<T, A, R> implements Collector<T, A, R> {
|
||||
/**
|
||||
* 创建新的结果容器,容器类型为A
|
||||
*/
|
||||
private final Supplier<A> supplier;
|
||||
/**
|
||||
* 将输入元素合并到结果容器中
|
||||
*/
|
||||
private final BiConsumer<A, T> accumulator;
|
||||
/**
|
||||
* 合并两个结果容器(并行流使用,将多个线程产生的结果容器合并)
|
||||
*/
|
||||
private final BinaryOperator<A> combiner;
|
||||
/**
|
||||
* 将结果容器转换成最终的表示
|
||||
*/
|
||||
private final Function<A, R> finisher;
|
||||
/**
|
||||
* 特征值枚举,见{@link Characteristics}
|
||||
* <ul>
|
||||
* <li>CONCURRENT: 表示结果容器只有一个(即使是在并行流的情况下)。
|
||||
* 只有在并行流且收集器不具备此特性的情况下,combiner()返回的lambda表达式才会执行(中间结果容器只有一个就无需合并)。
|
||||
* 设置此特性时意味着多个线程可以对同一个结果容器调用,因此结果容器必须是线程安全的。</li>
|
||||
* <li>UNORDERED: 表示流中的元素无序</li>
|
||||
* <li>IDENTITY_FINISH:表示中间结果容器类型与最终结果类型一致。设置此特性时finiser()方法不会被调用</li>
|
||||
* </ul>
|
||||
*/
|
||||
private final Set<Characteristics> characteristics;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param supplier 创建新的结果容器函数
|
||||
* @param accumulator 将输入元素合并到结果容器中函数
|
||||
* @param combiner 合并两个结果容器函数(并行流使用,将多个线程产生的结果容器合并)
|
||||
* @param finisher 将结果容器转换成最终的表示函数
|
||||
* @param characteristics 特征值枚举
|
||||
*/
|
||||
public SimpleCollector(Supplier<A> supplier,
|
||||
BiConsumer<A, T> accumulator,
|
||||
BinaryOperator<A> combiner,
|
||||
Function<A, R> finisher,
|
||||
Set<Characteristics> characteristics) {
|
||||
this.supplier = supplier;
|
||||
this.accumulator = accumulator;
|
||||
this.combiner = combiner;
|
||||
this.finisher = finisher;
|
||||
this.characteristics = characteristics;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param supplier 创建新的结果容器函数
|
||||
* @param accumulator 将输入元素合并到结果容器中函数
|
||||
* @param combiner 合并两个结果容器函数(并行流使用,将多个线程产生的结果容器合并)
|
||||
* @param characteristics 特征值枚举
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public SimpleCollector(Supplier<A> supplier,
|
||||
BiConsumer<A, T> accumulator,
|
||||
BinaryOperator<A> combiner,
|
||||
Set<Characteristics> characteristics) {
|
||||
this(supplier, accumulator, combiner, i -> (R) i, characteristics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiConsumer<A, T> accumulator() {
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<A> supplier() {
|
||||
return supplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryOperator<A> combiner() {
|
||||
return combiner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<A, R> finisher() {
|
||||
return finisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Characteristics> characteristics() {
|
||||
return characteristics;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package cn.hutool.core.stream;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
|
||||
import java.util.Spliterators;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* {@link Stream} 工具类
|
||||
*
|
||||
* @author looly
|
||||
* @since 5.6.7
|
||||
*/
|
||||
public class StreamUtil {
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> Stream<T> of(T... values) {
|
||||
if (null == values) {
|
||||
return null;
|
||||
}
|
||||
return Stream.of(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Iterable}转换为{@link Stream},默认非并行
|
||||
*
|
||||
* @param iterable 集合
|
||||
* @param <T> 集合元素类型
|
||||
* @return {@link Stream}
|
||||
*/
|
||||
public static <T> Stream<T> of(Iterable<T> iterable) {
|
||||
return of(iterable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Iterable}转换为{@link Stream}
|
||||
*
|
||||
* @param iterable 集合
|
||||
* @param parallel 是否并行
|
||||
* @param <T> 集合元素类型
|
||||
* @return {@link Stream}
|
||||
*/
|
||||
public static <T> Stream<T> of(Iterable<T> iterable, boolean parallel) {
|
||||
if (null == iterable) {
|
||||
return null;
|
||||
}
|
||||
return StreamSupport.stream(
|
||||
Spliterators.spliterator(CollUtil.toCollection(iterable), 0),
|
||||
parallel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过函数创建Stream
|
||||
*
|
||||
* @param seed 初始值
|
||||
* @param elementCreator 递进函数,每次调用此函数获取下一个值
|
||||
* @param limit 限制个数
|
||||
* @param <T> 创建元素类型
|
||||
* @return {@link Stream}
|
||||
*/
|
||||
public static <T> Stream<T> of(T seed, UnaryOperator<T> elementCreator, int limit) {
|
||||
return Stream.iterate(seed, elementCreator).limit(limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Stream中所有元素以指定分隔符,合并为一个字符串,对象默认调用toString方法
|
||||
*
|
||||
* @param stream {@link Stream}
|
||||
* @param delimiter 分隔符
|
||||
* @param <T> 元素类型
|
||||
* @return 字符串
|
||||
*/
|
||||
public static <T> String join(Stream<T> stream, CharSequence delimiter) {
|
||||
return stream.collect(CollectorUtil.joining(delimiter));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Stream中所有元素以指定分隔符,合并为一个字符串
|
||||
*
|
||||
* @param stream {@link Stream}
|
||||
* @param delimiter 分隔符
|
||||
* @param toStringFunc 元素转换为字符串的函数
|
||||
* @param <T> 元素类型
|
||||
* @return 字符串
|
||||
*/
|
||||
public static <T> String join(Stream<T> stream, CharSequence delimiter,
|
||||
Function<T, ? extends CharSequence> toStringFunc) {
|
||||
return stream.collect(CollectorUtil.joining(delimiter, toStringFunc));
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Java8的stream相关封装
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
package cn.hutool.core.stream;
|
@ -0,0 +1,16 @@
|
||||
package cn.hutool.core.stream;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class StreamUtilTest {
|
||||
|
||||
@Test
|
||||
public void ofTest(){
|
||||
final Stream<Integer> stream = StreamUtil.of(2, x -> x * 2, 4);
|
||||
final String result = stream.collect(CollectorUtil.joining(","));
|
||||
Assert.assertEquals("2,4,8,16", result);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user