From a079a809082e1e5cdd23502e7b377f0aaa65b032 Mon Sep 17 00:00:00 2001 From: LoveHuahua Date: Mon, 13 Feb 2023 21:48:23 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=B5=8B=E8=AF=95=E7=94=A8?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/core/stream/EasyStream.java | 86 +++++--- .../cn/hutool/core/stream/EasyStreamTest.java | 196 ++++++++++++------ 2 files changed, 186 insertions(+), 96 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/EasyStream.java b/hutool-core/src/main/java/cn/hutool/core/stream/EasyStream.java index 9001d19cf..1e2f4a919 100644 --- a/hutool-core/src/main/java/cn/hutool/core/stream/EasyStream.java +++ b/hutool-core/src/main/java/cn/hutool/core/stream/EasyStream.java @@ -104,7 +104,7 @@ public class EasyStream extends AbstractEnhancedWrappedStream 元素类型 * @return 包含单个元素的串行流 */ @@ -116,9 +116,9 @@ public class EasyStream extends AbstractEnhancedWrappedStream 元素类型 + * @param 元素类型 * @return 包含指定元素的串行流 - * 从一个安全数组中创建流 + * 从一个安全数组中创建流 */ @SafeVarargs @SuppressWarnings("varargs") @@ -130,7 +130,7 @@ public class EasyStream extends AbstractEnhancedWrappedStream 元素类型 + * @param 元素类型 * @return 流 */ public static EasyStream of(final Iterable iterable) { @@ -142,7 +142,7 @@ public class EasyStream extends AbstractEnhancedWrappedStream 元素类型 + * @param 元素类型 * @return 流 */ public static EasyStream of(final Iterable iterable, final boolean parallel) { @@ -157,7 +157,7 @@ public class EasyStream extends AbstractEnhancedWrappedStream 元素类型 + * @param 元素类型 * @return 流 */ public static EasyStream of(final Stream stream) { @@ -173,9 +173,9 @@ public class EasyStream extends AbstractEnhancedWrappedStream * - * @param 元素类型 + * @param 元素类型 * @param seed 初始值 - * @param f 用上一个元素作为参数执行并返回一个新的元素 + * @param f 用上一个元素作为参数执行并返回一个新的元素 * @return 无限有序流 */ public static EasyStream iterate(final T seed, final UnaryOperator f) { @@ -191,13 +191,14 @@ public class EasyStream extends AbstractEnhancedWrappedStream * - * @param 元素类型 - * @param seed 初始值 + * @param 元素类型 + * @param seed 初始值 * @param hasNext 条件值 - * @param next 用上一个元素作为参数执行并返回一个新的元素 + * @param next 用上一个元素作为参数执行并返回一个新的元素 * @return 无限有序流 */ - public static EasyStream iterate(final T seed, final Predicate hasNext, final UnaryOperator next) { + public static EasyStream iterate(final T seed, final Predicate hasNext, + final UnaryOperator next) { Objects.requireNonNull(next); Objects.requireNonNull(hasNext); return new EasyStream<>(StreamUtil.iterate(seed, hasNext, next)); @@ -209,7 +210,7 @@ public class EasyStream extends AbstractEnhancedWrappedStream 元素类型 - * @param s 用来生成元素的 {@code Supplier} + * @param s 用来生成元素的 {@code Supplier} * @return 无限串行无序流 */ public static EasyStream generate(final Supplier s) { @@ -224,8 +225,8 @@ public class EasyStream extends AbstractEnhancedWrappedStream从重复串行流进行拼接时可能会导致深度调用链甚至抛出 {@code StackOverflowException}

* * @param 元素类型 - * @param a 第一个流 - * @param b 第二个流 + * @param a 第一个流 + * @param b 第二个流 * @return 拼接两个流之后的流 */ public static EasyStream concat(final Stream a, final Stream b) { @@ -235,12 +236,13 @@ public class EasyStream extends AbstractEnhancedWrappedStream split(final CharSequence str, final String regex) { - return Opt.ofBlankAble(str).map(CharSequence::toString).map(s -> s.split(regex)).map(EasyStream::of).orElseGet(EasyStream::empty); + return Opt.ofBlankAble(str).map(CharSequence::toString).map(s -> s.split(regex)).map(EasyStream::of) + .orElseGet(EasyStream::empty); } // --------------------------------------------------------------- Static method end @@ -251,7 +253,7 @@ public class EasyStream extends AbstractEnhancedWrappedStream 函数执行后返回的类型 + * @param 函数执行后返回的类型 * @return 返回叠加操作后的流 */ @Override @@ -272,8 +274,6 @@ public class EasyStream extends AbstractEnhancedWrappedStream extends AbstractEnhancedWrappedStream mapper) { - return stream.map(mapper).reduce(BigDecimal.ZERO, BigDecimal::add); + return stream.map(mapper).reduce(BigDecimal.ZERO, BigDecimal::add); + } + + + /** + * 计算bigDecimal平均值 并以四舍五入的方式保留2位精度 + * + * @param mapper 映射 + * @return 如果元素的长度为0 那么会返回为空的opt + */ + public Opt avg(final Function mapper) { + return avg(mapper, 2); + } + + + /** + * 计算bigDecimal平均值 并以四舍五入的方式保留scale的进度 + * + * @param mapper 映射 + * @param scale 精度 + * @return 如果元素的长度为0 那么会返回为空的opt + */ + public Opt avg(final Function mapper, int scale) { + return avg(mapper, scale, RoundingMode.HALF_UP); } /** * 计算bigDecimal平均值 + * * @param mapper 映射 * @param scale 精度 * @param roundingMode 舍入模式 * @return 如果元素的长度为0 那么会返回为空的opt */ - public Opt avg(final Function mapper,int scale,RoundingMode roundingMode){ + public Opt avg(final Function mapper, int scale, RoundingMode roundingMode) { //元素列表 List bigDecimalList = stream.map(mapper).collect(Collectors.toList()); - if (CollUtil.isEmpty(bigDecimalList)){ + if (CollUtil.isEmpty(bigDecimalList)) { return Opt.ofNullable(null); } - return Opt.of(EasyStream.of(bigDecimalList).reduce(BigDecimal.ZERO, BigDecimal::add).divide(NumberUtil.toBigDecimal(bigDecimalList.size()),scale, roundingMode)); + return Opt.of(EasyStream.of(bigDecimalList).reduce(BigDecimal.ZERO, BigDecimal::add) + .divide(NumberUtil.toBigDecimal(bigDecimalList.size()), scale, roundingMode)); } - - /** * 计算int平均值 * @@ -367,7 +390,6 @@ public class EasyStream extends AbstractEnhancedWrappedStream extends AbstractEnhancedWrappedStream{@code - * accept(t) - * return this; - * } + *
{@code
+		 * 						    accept(t)
+		 * 						    return this;
+		 *                      }
*/ default Builder add(final T t) { accept(t); diff --git a/hutool-core/src/test/java/cn/hutool/core/stream/EasyStreamTest.java b/hutool-core/src/test/java/cn/hutool/core/stream/EasyStreamTest.java index 5b83598a9..f44a0570a 100644 --- a/hutool-core/src/test/java/cn/hutool/core/stream/EasyStreamTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/stream/EasyStreamTest.java @@ -2,8 +2,10 @@ package cn.hutool.core.stream; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.lang.Opt; import cn.hutool.core.map.MapUtil; import cn.hutool.core.math.NumberUtil; +import java.math.RoundingMode; import org.junit.Assert; import org.junit.Test; @@ -85,10 +87,10 @@ public class EasyStreamTest { final List orders = Arrays.asList(1, 2, 3, 2); final List list = Arrays.asList("dromara", "guava", "sweet", "hutool"); final Map map = MapUtil.builder() - .put(1, "dromara") - .put(2, "hutool") - .put(3, "sweet") - .build(); + .put(1, "dromara") + .put(2, "hutool") + .put(3, "sweet") + .build(); final Map toZip = EasyStream.of(orders).toZip(list); Assert.assertEquals(map, toZip); @@ -126,15 +128,15 @@ public class EasyStreamTest { final List list = Arrays.asList(1, 2, 3); final Map> group = EasyStream.of(list).group(String::valueOf); Assert.assertEquals( - new HashMap>() { - private static final long serialVersionUID = 1L; + new HashMap>() { + private static final long serialVersionUID = 1L; - { - put("1", singletonList(1)); - put("2", singletonList(2)); - put("3", singletonList(3)); - } - }, group); + { + put("1", singletonList(1)); + put("2", singletonList(2)); + put("3", singletonList(3)); + } + }, group); } @Test @@ -144,7 +146,7 @@ public class EasyStreamTest { Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), mapIndex); // 并行流时正常 Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), - EasyStream.of("dromara", "hutool", "sweet").parallel().mapIdx((e, i) -> i + 1 + "." + e).toList()); + EasyStream.of("dromara", "hutool", "sweet").parallel().mapIdx((e, i) -> i + 1 + "." + e).toList()); } @Test @@ -185,7 +187,8 @@ public class EasyStreamTest { Assert.assertEquals(ListUtil.sort(collect2), ListUtil.sort(distinctBy2)); Assert.assertEquals( - 4, EasyStream.of(1, 2, 2, null, 3, null).parallel(true).distinct(t -> Objects.isNull(t) ? null : t.toString()).sequential().count() + 4, EasyStream.of(1, 2, 2, null, 3, null).parallel(true) + .distinct(t -> Objects.isNull(t) ? null : t.toString()).sequential().count() ); } @@ -221,28 +224,28 @@ public class EasyStreamTest { Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), mapIndex); // 并行流时正常 Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), - EasyStream.of("dromara", "hutool", "sweet").parallel() - .flatMapIdx((e, i) -> EasyStream.of(i + 1 + "." + e)).toList()); + EasyStream.of("dromara", "hutool", "sweet").parallel() + .flatMapIdx((e, i) -> EasyStream.of(i + 1 + "." + e)).toList()); } @Test public void testPeek() { EasyStream.of("one", "two", "three", "four") - .filter(e -> e.length() == 4) - .peek(e -> Assert.assertEquals("four", e)) - .map(String::toUpperCase) - .peek(e -> Assert.assertEquals("FOUR", e)) - .collect(Collectors.toList()); + .filter(e -> e.length() == 4) + .peek(e -> Assert.assertEquals("four", e)) + .map(String::toUpperCase) + .peek(e -> Assert.assertEquals("FOUR", e)) + .collect(Collectors.toList()); } @Test public void testPeekIdx() { EasyStream.of("one", "two", "three", "four") - .filter(e -> e.length() == 4) - .peekIdx((e, i) -> Assert.assertEquals("four:0", e + ":" + i)) - .map(String::toUpperCase) - .peekIdx((e, i) -> Assert.assertEquals("FOUR:0", e + ":" + i)) - .collect(Collectors.toList()); + .filter(e -> e.length() == 4) + .peekIdx((e, i) -> Assert.assertEquals("four:0", e + ":" + i)) + .map(String::toUpperCase) + .peekIdx((e, i) -> Assert.assertEquals("FOUR:0", e + ":" + i)) + .collect(Collectors.toList()); } @Test @@ -278,7 +281,7 @@ public class EasyStreamTest { Assert.assertEquals(Arrays.asList("dromara", "hutool"), filterIndex); // 并行流时正常 Assert.assertEquals(Arrays.asList("dromara", "hutool"), - EasyStream.of("dromara", "hutool", "sweet").parallel().filterIdx((e, i) -> i < 2).toList()); + EasyStream.of("dromara", "hutool", "sweet").parallel().filterIdx((e, i) -> i < 2).toList()); } @Test @@ -384,23 +387,23 @@ public class EasyStreamTest { final List list = EasyStream.iterate(1, i -> i <= 10, i -> i + 1).toList(); final List res1 = EasyStream.of(list) - // 舍弃 5 - .takeWhile(e -> e < 5) - // 过滤奇数 - .filter(e -> (e & 1) == 0) - // 反序 - .sorted(Comparator.reverseOrder()) - .map(String::valueOf) - .toList(); + // 舍弃 5 + .takeWhile(e -> e < 5) + // 过滤奇数 + .filter(e -> (e & 1) == 0) + // 反序 + .sorted(Comparator.reverseOrder()) + .map(String::valueOf) + .toList(); Assert.assertEquals(Arrays.asList("4", "2"), res1); final List res2 = EasyStream.iterate(1, i -> i + 1) - .parallel() - .takeWhile(e -> e < 5) - .map(String::valueOf) - .map(Integer::valueOf) - .sorted(Comparator.naturalOrder()) - .toList(); + .parallel() + .takeWhile(e -> e < 5) + .map(String::valueOf) + .map(Integer::valueOf) + .sorted(Comparator.naturalOrder()) + .toList(); Assert.assertEquals(Arrays.asList(1, 2, 3, 4), res2); } @@ -410,25 +413,25 @@ public class EasyStreamTest { final List list = EasyStream.iterate(1, i -> i <= 10, i -> i + 1).toList(); final List res1 = EasyStream.of(list) - // 舍弃 5之前的数字 - .dropWhile(e -> e < 5) - // 过滤偶数 - .filter(e -> (e & 1) == 1) - // 反序 - .sorted(Comparator.reverseOrder()) - .map(String::valueOf) - .toList(); + // 舍弃 5之前的数字 + .dropWhile(e -> e < 5) + // 过滤偶数 + .filter(e -> (e & 1) == 1) + // 反序 + .sorted(Comparator.reverseOrder()) + .map(String::valueOf) + .toList(); Assert.assertEquals(Arrays.asList("9", "7", "5"), res1); final List res2 = EasyStream.of(list) - .parallel() - .dropWhile(e -> e < 5) - // 过滤偶数 - .filter(e -> (e & 1) == 1) - .map(String::valueOf) - .map(Integer::valueOf) - .sorted(Comparator.naturalOrder()) - .toList(); + .parallel() + .dropWhile(e -> e < 5) + // 过滤偶数 + .filter(e -> (e & 1) == 1) + .map(String::valueOf) + .map(Integer::valueOf) + .sorted(Comparator.naturalOrder()) + .toList(); Assert.assertEquals(Arrays.asList(5, 7, 9), res2); } @@ -440,6 +443,7 @@ public class EasyStreamTest { @Test public void testIntSumAndAvg() { + //测试int类型的总和 int sum = EasyStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).sum(Integer::intValue); Assert.assertEquals(sum, 55); @@ -447,38 +451,102 @@ public class EasyStreamTest { List integerList = new ArrayList<>(); int emptySum = EasyStream.of(integerList).sum(Integer::intValue); Assert.assertEquals(emptySum, 0); + + //测试平均值 + OptionalDouble avg = EasyStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).avg(Integer::intValue); + Assert.assertEquals(avg.getAsDouble(), 5.5, 2); + + //测试元素为空 + OptionalDouble emptyAvg = EasyStream.of(integerList).avg(Integer::intValue); + Assert.assertFalse(emptyAvg.isPresent()); + } @Test public void testDoubleSumAndAvg() { + //测试double类型的sum double doubleSum = EasyStream.of(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10).sum(Double::doubleValue); - Assert.assertEquals(doubleSum, 59.6,2); + Assert.assertEquals(doubleSum, 59.6, 2); + //测试double类型的sum 无元素double List doubleList = new ArrayList<>(); double emptySum = EasyStream.of(doubleList).sum(Double::doubleValue); - Assert.assertEquals(emptySum, 0.0,2); + Assert.assertEquals(emptySum, 0.0, 2); + + //测试double类型的avg + OptionalDouble doubleAvg = EasyStream.of(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10) + .avg(Double::doubleValue); + Assert.assertEquals(doubleAvg.getAsDouble(), 5.96, 2); + + //测试double类型的 空元素的avg + OptionalDouble emptyDoubleAvg = EasyStream.of(doubleList).avg(Double::doubleValue); + Assert.assertFalse(emptyDoubleAvg.isPresent()); } @Test public void testLongSumAndAvg() { + //测试long类型的sum long sum = EasyStream.of(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L).sum(Long::longValue); Assert.assertEquals(sum, 55); + //测试long类型的空元素 sum List longList = new ArrayList<>(); - double emptySum = EasyStream.of(longList).sum(Long::longValue); + long emptySum = EasyStream.of(longList).sum(Long::longValue); Assert.assertEquals(emptySum, 0L); + //测试long类型的avg + OptionalDouble doubleAvg = EasyStream.of(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L).avg(Long::longValue); + Assert.assertEquals(doubleAvg.getAsDouble(), 5.5, 2); + + //测试long类型的avg 空元素 + OptionalDouble emptyDoubleAvg = EasyStream.of(longList).avg(Long::longValue); + Assert.assertFalse(emptyDoubleAvg.isPresent()); + + } @Test public void testBigDecimalSumAndAvg() { - BigDecimal sum = EasyStream.of(NumberUtil.toBigDecimal(1.1), NumberUtil.toBigDecimal(2.2), NumberUtil.toBigDecimal(3.3), NumberUtil.toBigDecimal(4.4), NumberUtil.toBigDecimal(5.5), NumberUtil.toBigDecimal(6.6), NumberUtil.toBigDecimal(7.7), NumberUtil.toBigDecimal(8.8), NumberUtil.toBigDecimal(9.9), NumberUtil.toBigDecimal(10.10)).sum(Function.identity()); - Assert.assertEquals(sum, 59.6); + //测试bigDecimal的sum + BigDecimal sum = EasyStream.of(NumberUtil.toBigDecimal(1.1), NumberUtil.toBigDecimal(2.2), + NumberUtil.toBigDecimal(3.3), NumberUtil.toBigDecimal(4.4), NumberUtil.toBigDecimal(5.5), + NumberUtil.toBigDecimal(6.6), NumberUtil.toBigDecimal(7.7), NumberUtil.toBigDecimal(8.8), + NumberUtil.toBigDecimal(9.9), NumberUtil.toBigDecimal(10.10)).sum(Function.identity()); + Assert.assertEquals(sum, NumberUtil.toBigDecimal(59.6)); - List bigDecimalList = new ArrayList<>(); - BigDecimal emptySum = EasyStream.of(bigDecimalList).sum(Function.identity()); + //测试bigDecimal的sum 空元素 + List bigDecimalEmptyList = new ArrayList<>(); + BigDecimal emptySum = EasyStream.of(bigDecimalEmptyList).sum(Function.identity()); Assert.assertEquals(emptySum, BigDecimal.ZERO); + //测试bigDecimal的avg + Opt bigDecimalAvgFullParam = EasyStream.of(NumberUtil.toBigDecimal(1.1), + NumberUtil.toBigDecimal(2.2), NumberUtil.toBigDecimal(3.3), NumberUtil.toBigDecimal(4.4), + NumberUtil.toBigDecimal(5.5), NumberUtil.toBigDecimal(6.6), NumberUtil.toBigDecimal(7.7), + NumberUtil.toBigDecimal(8.8), NumberUtil.toBigDecimal(9.9), NumberUtil.toBigDecimal(10.10)) + .avg(Function.identity(), 2, RoundingMode.HALF_UP); + Assert.assertEquals(bigDecimalAvgFullParam.get(), NumberUtil.toBigDecimal(5.96)); + + Opt bigDecimalAvgOneParam = EasyStream.of(NumberUtil.toBigDecimal(1.1), + NumberUtil.toBigDecimal(2.2), NumberUtil.toBigDecimal(3.3), NumberUtil.toBigDecimal(4.4), + NumberUtil.toBigDecimal(5.5), NumberUtil.toBigDecimal(6.6), NumberUtil.toBigDecimal(7.7), + NumberUtil.toBigDecimal(8.8), NumberUtil.toBigDecimal(9.9), NumberUtil.toBigDecimal(10.10)) + .avg(Function.identity()); + Assert.assertEquals(bigDecimalAvgOneParam.get(), NumberUtil.toBigDecimal(5.96)); + + Opt bigDecimalAvgTwoParam = EasyStream.of(NumberUtil.toBigDecimal(1.1), + NumberUtil.toBigDecimal(2.2), NumberUtil.toBigDecimal(3.3), NumberUtil.toBigDecimal(4.4), + NumberUtil.toBigDecimal(5.5), NumberUtil.toBigDecimal(6.6), NumberUtil.toBigDecimal(7.7), + NumberUtil.toBigDecimal(8.8), NumberUtil.toBigDecimal(9.9), NumberUtil.toBigDecimal(10.10)) + .avg(Function.identity(), 2); + Assert.assertEquals(bigDecimalAvgTwoParam.get(), NumberUtil.toBigDecimal(5.96)); + + //测试bigDecimal的avg 空元素 + Opt emptyBigDecimalAvg = EasyStream.of(bigDecimalEmptyList) + .avg(Function.identity(), 2, RoundingMode.HALF_UP); + Assert.assertFalse(emptyBigDecimalAvg.isPresent()); + + } }