diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/AbstractEnhancedWrappedStream.java b/hutool-core/src/main/java/cn/hutool/core/stream/AbstractEnhancedWrappedStream.java index 25e4bc2b3..687d47ea8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/stream/AbstractEnhancedWrappedStream.java +++ b/hutool-core/src/main/java/cn/hutool/core/stream/AbstractEnhancedWrappedStream.java @@ -8,7 +8,7 @@ import java.util.stream.Stream; * * @param 流中的元素类型 * @param {@link AbstractEnhancedWrappedStream}的实现类类型 - * @author huangchengxing + * @author huangchengxing VampireAchao * @see EasyStream * @see EntryStream * @since 6.0.0 diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java b/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java index 94a55651f..14ffe6b6c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java @@ -134,7 +134,7 @@ public class CollectorUtil { * @return {@link Collector} */ public static Collector> groupingBy(final Function classifier, - final Collector downstream) { + final Collector downstream) { return groupingBy(classifier, HashMap::new, downstream); } @@ -273,14 +273,14 @@ public class CollectorUtil { /** * 将流转为{@link EntryStream} * - * @param keyMapper 键的映射方法 - * @param 输入元素类型 - * @param 元素的键类型 + * @param keyMapper 键的映射方法 + * @param 输入元素类型 + * @param 元素的键类型 * @return 收集器 * @since 6.0.0 */ public static Collector, EntryStream> toEntryStream( - Function keyMapper) { + Function keyMapper) { return toEntryStream(keyMapper, Function.identity()); } @@ -361,4 +361,14 @@ public class CollectorUtil { return transform(ArrayList::new, mapper); } + /** + * 用于{@code Stream} 转 Map 的情况 + * + * @param key类型 + * @param value类型 + * @return map + */ + public static Collector, ?, Map> entryToMap() { + return toMap(Map.Entry::getKey, Map.Entry::getValue); + } } diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/TerminableWrappedStream.java b/hutool-core/src/main/java/cn/hutool/core/stream/TerminableWrappedStream.java index 17344f511..e329f9901 100644 --- a/hutool-core/src/main/java/cn/hutool/core/stream/TerminableWrappedStream.java +++ b/hutool-core/src/main/java/cn/hutool/core/stream/TerminableWrappedStream.java @@ -17,7 +17,7 @@ import java.util.stream.Stream; * * @param 流中的元素类型 * @param {@link TerminableWrappedStream}的实现类类型 - * @author huangchengxing + * @author huangchengxing VampireAchao * @since 6.0.0 */ public interface TerminableWrappedStream> extends WrappedStream { diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/TransformableWrappedStream.java b/hutool-core/src/main/java/cn/hutool/core/stream/TransformableWrappedStream.java index d621278da..b90b911d4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/stream/TransformableWrappedStream.java +++ b/hutool-core/src/main/java/cn/hutool/core/stream/TransformableWrappedStream.java @@ -3,7 +3,6 @@ package cn.hutool.core.stream; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.iter.IterUtil; import cn.hutool.core.lang.Console; -import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.mutable.MutableInt; import cn.hutool.core.lang.mutable.MutableObj; import cn.hutool.core.map.MapUtil; @@ -24,7 +23,7 @@ import java.util.stream.StreamSupport; * * @param 流中的元素类型 * @param {@link TransformableWrappedStream}的实现类类型 - * @author huangchengxing + * @author huangchengxing VampireAchao * @since 6.0.0 */ public interface TransformableWrappedStream> extends WrappedStream { @@ -40,24 +39,15 @@ public interface TransformableWrappedStream EasyStream zip( - final Iterable other, - final BiFunction zipper) { + final Iterable other, + final BiFunction zipper) { Objects.requireNonNull(zipper); - final Spliterator keys = spliterator(); - final Spliterator values = Opt.ofNullable(other).map(Iterable::spliterator).orElseGet(Spliterators::emptySpliterator); - // 获取两个Spliterator的中较小的数量 - // 如果Spliterator经过流操作, getExactSizeIfKnown()可能会返回-1, 所以默认大小为 ArrayList.DEFAULT_CAPACITY - final int sizeIfKnown = (int) Math.max(Math.min(keys.getExactSizeIfKnown(), values.getExactSizeIfKnown()), 10); - final List list = new ArrayList<>(sizeIfKnown); - // 保存第一个Spliterator的值 - final MutableObj key = new MutableObj<>(); - // 保存第二个Spliterator的值 - final MutableObj value = new MutableObj<>(); - // 当两个Spliterator中都还有剩余元素时 - while (keys.tryAdvance(key::set) && values.tryAdvance(value::set)) { - list.add(zipper.apply(key.get(), value.get())); + Map idxIdentityMap = mapIdx((e, idx) -> MapUtil.entry(idx, e)).collect(CollectorUtil.entryToMap()); + Map idxOtherMap = EasyStream.of(other).mapIdx((e, idx) -> MapUtil.entry(idx, e)).collect(CollectorUtil.entryToMap()); + if (idxIdentityMap.size() <= idxOtherMap.size()) { + return EasyStream.of(idxIdentityMap.keySet(), isParallel()).map(k -> zipper.apply(idxIdentityMap.get(k), idxOtherMap.get(k))); } - return EasyStream.of(list).parallel(isParallel()).onClose(unwrap()::close); + return EasyStream.of(idxOtherMap.keySet(), isParallel()).map(k -> zipper.apply(idxIdentityMap.get(k), idxOtherMap.get(k))); } /** @@ -78,9 +68,9 @@ public interface TransformableWrappedStream>of(EasyStream.of(list, isParallel())); } return EasyStream.iterate(0, i -> i < size, i -> i + batchSize) - .map(skip -> EasyStream.of(list.subList(skip, Math.min(size, skip + batchSize)), isParallel())) - .parallel(isParallel()) - .onClose(unwrap()::close); + .map(skip -> EasyStream.of(list.subList(skip, Math.min(size, skip + batchSize)), isParallel())) + .parallel(isParallel()) + .onClose(unwrap()::close); } /** @@ -114,8 +104,8 @@ public interface TransformableWrappedStream 键类型 + * @param keyMapper 键的映射方法 + * @param 键类型 * @return {@link EntryStream}实例 */ default EntryStream toEntries(final Function keyMapper) { @@ -159,7 +149,7 @@ public interface TransformableWrappedStream elements = unwrap().collect(Collectors.toList()); return wrap(ListUtil.splice(elements, start, deleteCount, items).stream()) - .parallel(isParallel()); + .parallel(isParallel()); } /** @@ -262,6 +252,7 @@ public interface TransformableWrappedStream>> recursiveRef = new MutableObj<>(); - @SuppressWarnings("unchecked") - final Function> recursive = e -> EasyStream.of(childrenGetter.apply(e)) - .flat(recursiveRef.get()) - .unshift(e); + @SuppressWarnings("unchecked") final Function> recursive = e -> EasyStream.of(childrenGetter.apply(e)) + .flat(recursiveRef.get()) + .unshift(e); recursiveRef.set(recursive); return wrap(flatMap(recursive).peek(e -> childrenSetter.accept(e, null))); } diff --git a/hutool-core/src/test/java/cn/hutool/core/stream/AbstractEnhancedWrappedStreamTest.java b/hutool-core/src/test/java/cn/hutool/core/stream/AbstractEnhancedWrappedStreamTest.java index 6922d30b5..12d8e1197 100644 --- a/hutool-core/src/test/java/cn/hutool/core/stream/AbstractEnhancedWrappedStreamTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/stream/AbstractEnhancedWrappedStreamTest.java @@ -33,7 +33,7 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testToUnmodifiableList() { final List list = wrap(1, 2, 3) - .toUnmodifiableList(); + .toUnmodifiableList(); Assert.assertThrows(UnsupportedOperationException.class, () -> list.remove(0)); } @@ -47,7 +47,7 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testToUnmodifiableSet() { final Set set = wrap(1, 2, 3) - .toUnmodifiableSet(); + .toUnmodifiableSet(); Assert.assertThrows(UnsupportedOperationException.class, () -> set.remove(0)); } @@ -98,8 +98,8 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testFindFirst() { final List list = asList(1, 2, 3); - Assert.assertEquals((Integer)1, wrap(list).findFirst(t -> (t & 1) == 1).orElse(null)); - Assert.assertEquals((Integer)1, wrap(list).filter(t -> (t & 1) == 1).findFirst().orElse(null)); + Assert.assertEquals((Integer) 1, wrap(list).findFirst(t -> (t & 1) == 1).orElse(null)); + Assert.assertEquals((Integer) 1, wrap(list).filter(t -> (t & 1) == 1).findFirst().orElse(null)); } @Test @@ -111,7 +111,7 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testFindLast() { final List list = asList(1, 2, 3); - Assert.assertEquals((Integer)3, wrap(list).findLast(t -> (t & 1) == 1).orElse(null)); + Assert.assertEquals((Integer) 3, wrap(list).findLast(t -> (t & 1) == 1).orElse(null)); } @Test @@ -123,7 +123,7 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testAt() { final List list = asList(1, 2, 3); - Assert.assertEquals((Integer)3, wrap(list).at(2).orElse(null)); + Assert.assertEquals((Integer) 3, wrap(list).at(2).orElse(null)); } @Test @@ -219,13 +219,13 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testMapToInt() { final int[] array = wrap(1, 2, 3).mapToInt(Integer::intValue).toArray(); - Assert.assertArrayEquals(new int[] {1, 2, 3}, array); + Assert.assertArrayEquals(new int[]{1, 2, 3}, array); } @Test public void testMapToLong() { final long[] array = wrap(1L, 2L, 3L).mapToLong(Long::intValue).toArray(); - Assert.assertArrayEquals(new long[] {1L, 2L, 3L}, array); + Assert.assertArrayEquals(new long[]{1L, 2L, 3L}, array); } @Test @@ -239,13 +239,13 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testFlatMapToInt() { final int[] array = wrap(1, 2, 3).flatMapToInt(IntStream::of).toArray(); - Assert.assertArrayEquals(new int[] {1, 2, 3}, array); + Assert.assertArrayEquals(new int[]{1, 2, 3}, array); } @Test public void testFlatMapToLong() { final long[] array = wrap(1L, 2L, 3L).flatMapToLong(LongStream::of).toArray(); - Assert.assertArrayEquals(new long[] {1L, 2L, 3L}, array); + Assert.assertArrayEquals(new long[]{1L, 2L, 3L}, array); } @Test @@ -312,28 +312,28 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testReduce() { - Assert.assertEquals((Integer)6, wrap(1, 2, 3).reduce(Integer::sum).orElse(null)); - Assert.assertEquals((Integer)6, wrap(1, 2, 3).reduce(0, Integer::sum)); - Assert.assertEquals((Integer)6, wrap(1, 2, 3).reduce(0, Integer::sum, Integer::sum)); + Assert.assertEquals((Integer) 6, wrap(1, 2, 3).reduce(Integer::sum).orElse(null)); + Assert.assertEquals((Integer) 6, wrap(1, 2, 3).reduce(0, Integer::sum)); + Assert.assertEquals((Integer) 6, wrap(1, 2, 3).reduce(0, Integer::sum, Integer::sum)); } @Test public void testCollect() { Assert.assertEquals(asList(1, 2, 3), wrap(1, 2, 3).collect(Collectors.toList())); Assert.assertEquals( - asList(1, 2, 3), - wrap(1, 2, 3).collect(ArrayList::new, List::add, List::addAll) + asList(1, 2, 3), + wrap(1, 2, 3).collect(ArrayList::new, List::add, List::addAll) ); } @Test public void testMin() { - Assert.assertEquals((Integer)1, wrap(1, 2, 3).min(Comparator.comparingInt(Integer::intValue)).orElse(null)); + Assert.assertEquals((Integer) 1, wrap(1, 2, 3).min(Comparator.comparingInt(Integer::intValue)).orElse(null)); } @Test public void testMax() { - Assert.assertEquals((Integer)3, wrap(1, 2, 3).max(Comparator.comparingInt(Integer::intValue)).orElse(null)); + Assert.assertEquals((Integer) 3, wrap(1, 2, 3).max(Comparator.comparingInt(Integer::intValue)).orElse(null)); } @Test @@ -377,7 +377,7 @@ public class AbstractEnhancedWrappedStreamTest { public void testSpliterator() { final Spliterator iter1 = Stream.of(1, 2, 3).spliterator(); final Spliterator iter2 = wrap(1, 2, 3).spliterator(); - Assert.assertEquals(iter1.trySplit().estimateSize(), iter2.trySplit().estimateSize()); + Assert.assertEquals(iter1.trySplit().estimateSize(), iter2.trySplit().estimateSize()); } @Test @@ -412,7 +412,7 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testReverse() { Assert.assertEquals( - asList(3, 2, 1), wrap(1, 2, 3).reverse().toList() + asList(3, 2, 1), wrap(1, 2, 3).reverse().toList() ); } @@ -424,15 +424,15 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testSplice() { Assert.assertEquals( - asList(1, 4, 5), wrap(1, 2, 3).splice(1, 2, 4, 5).toList() + asList(1, 4, 5), wrap(1, 2, 3).splice(1, 2, 4, 5).toList() ); } @Test public void testTakeWhile() { Assert.assertEquals( - asList(1, 2), - wrap(1, 2, 3, 4).takeWhile(i -> !Objects.equals(i, 3)).toList() + asList(1, 2), + wrap(1, 2, 3, 4).takeWhile(i -> !Objects.equals(i, 3)).toList() ); } @@ -440,15 +440,15 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testDropWhile() { Assert.assertEquals( - asList(3, 4), - wrap(1, 2, 3, 4).dropWhile(i -> !Objects.equals(i, 3)).toList() + asList(3, 4), + wrap(1, 2, 3, 4).dropWhile(i -> !Objects.equals(i, 3)).toList() ); } @Test public void testDistinct() { Assert.assertEquals( - asList(1, 2, 3), wrap(1, 1, 2, 3).distinct().toList() + asList(1, 2, 3), wrap(1, 1, 2, 3).distinct().toList() ); } @@ -460,41 +460,41 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testPush() { Assert.assertEquals( - asList(1, 2, 3), wrap(1).push(2, 3).toList() + asList(1, 2, 3), wrap(1).push(2, 3).toList() ); } @Test public void testUnshift() { Assert.assertEquals( - asList(1, 2, 3), wrap(3).unshift(1, 2).toList() + asList(1, 2, 3), wrap(3).unshift(1, 2).toList() ); } @Test public void testAppend() { Assert.assertEquals( - asList(1, 2, 3), wrap(1).append(asList(2, 3)).toList() + asList(1, 2, 3), wrap(1).append(asList(2, 3)).toList() ); Assert.assertEquals( - asList(1, 2, 3), wrap(1, 2, 3).append(null).toList() + asList(1, 2, 3), wrap(1, 2, 3).append(null).toList() ); } @Test public void testPrepend() { Assert.assertEquals( - asList(1, 2, 3), wrap(3).prepend(asList(1, 2)).toList() + asList(1, 2, 3), wrap(3).prepend(asList(1, 2)).toList() ); Assert.assertEquals( - asList(1, 2, 3), wrap(1, 2, 3).prepend(null).toList() + asList(1, 2, 3), wrap(1, 2, 3).prepend(null).toList() ); } @Test public void testNonNull() { Assert.assertEquals( - asList(1, 3), wrap(1, null, 3).nonNull().toList() + asList(1, 3), wrap(1, null, 3).nonNull().toList() ); } @@ -502,11 +502,11 @@ public class AbstractEnhancedWrappedStreamTest { public void testFilterIdx() { final List indexes = new ArrayList<>(); Assert.assertEquals( - asList(1, 3), - wrap(1, 2, 3).filterIdx((t, i) -> { - indexes.add(i); - return (t & 1) == 1; - }).toList() + asList(1, 3), + wrap(1, 2, 3).filterIdx((t, i) -> { + indexes.add(i); + return (t & 1) == 1; + }).toList() ); Assert.assertEquals(asList(0, 1, 2), indexes); } @@ -514,14 +514,14 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testFilter() { Assert.assertEquals( - asList(1, 3), wrap(1, 2, 3).filter(i -> (i & 1) == 1).toList() + asList(1, 3), wrap(1, 2, 3).filter(i -> (i & 1) == 1).toList() ); } @Test public void testFlatMap() { Assert.assertEquals( - asList(1, 2, 3), wrap(1, 2, 3).flatMap(Stream::of).toList() + asList(1, 2, 3), wrap(1, 2, 3).flatMap(Stream::of).toList() ); } @@ -529,10 +529,10 @@ public class AbstractEnhancedWrappedStreamTest { public void testFlatMapIdx() { final List indexes = new ArrayList<>(); Assert.assertEquals( - asList(1, 2, 3), wrap(1, 2, 3).flatMapIdx((t, i) -> { - indexes.add(i); - return Stream.of(t); - }).toList() + asList(1, 2, 3), wrap(1, 2, 3).flatMapIdx((t, i) -> { + indexes.add(i); + return Stream.of(t); + }).toList() ); Assert.assertEquals(asList(0, 1, 2), indexes); } @@ -540,14 +540,14 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testFlat() { Assert.assertEquals( - asList(1, 2, 3), wrap(1, 2, 3).flat(Collections::singletonList).toList() + asList(1, 2, 3), wrap(1, 2, 3).flat(Collections::singletonList).toList() ); } @Test public void testFlatNonNull() { Assert.assertEquals( - asList(2, 3), wrap(null, 2, 3).flatNonNull(Collections::singletonList).toList() + asList(2, 3), wrap(null, 2, 3).flatNonNull(Collections::singletonList).toList() ); } @@ -560,14 +560,14 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testMap() { Assert.assertEquals( - asList("1", "2", "3"), wrap(1, 2, 3).map(String::valueOf).toList() + asList("1", "2", "3"), wrap(1, 2, 3).map(String::valueOf).toList() ); } @Test public void testMapNonNull() { Assert.assertEquals( - asList("3"), wrap(null, 2, 3, 4).mapNonNull(t -> ((t & 1) == 0) ? null : String.valueOf(t)).toList() + asList("3"), wrap(null, 2, 3, 4).mapNonNull(t -> ((t & 1) == 0) ? null : String.valueOf(t)).toList() ); } @@ -575,10 +575,10 @@ public class AbstractEnhancedWrappedStreamTest { public void testMapIdx() { final List indexes = new ArrayList<>(); Assert.assertEquals( - asList("1", "2", "3"), wrap(1, 2, 3).mapIdx((t, i) -> { - indexes.add(i); - return String.valueOf(t); - }).toList() + asList("1", "2", "3"), wrap(1, 2, 3).mapIdx((t, i) -> { + indexes.add(i); + return String.valueOf(t); + }).toList() ); Assert.assertEquals(asList(0, 1, 2), indexes); } @@ -586,10 +586,10 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testMapMulti() { Assert.assertEquals( - asList(1, 2, 3), - wrap(1, 2, 3).mapMulti((t, builder) -> { - builder.accept(t); - }).toList() + asList(1, 2, 3), + wrap(1, 2, 3).mapMulti((t, builder) -> { + builder.accept(t); + }).toList() ); } @@ -613,19 +613,19 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testToEntries() { - final Map expect = new HashMap(){{ + final Map expect = new HashMap() {{ put(1, 1); put(2, 2); put(3, 3); }}; Map map = EasyStream.of(1, 2, 3) - .toEntries(Function.identity(), Function.identity()) - .toMap(); + .toEntries(Function.identity(), Function.identity()) + .toMap(); Assert.assertEquals(expect, map); map = EasyStream.of(1, 2, 3) - .toEntries(Function.identity()) - .toMap(); + .toEntries(Function.identity()) + .toMap(); Assert.assertEquals(expect, map); } @@ -636,7 +636,7 @@ public class AbstractEnhancedWrappedStreamTest { List zip = wrap(orders).zip(list, (e1, e2) -> e1 + "." + e2).toList(); Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), zip); - zip = wrap((Stream)EasyStream.iterate(1, i -> i + 1)).zip(list, (e1, e2) -> e1 + "." + e2).toList(); + zip = wrap((Stream) EasyStream.iterate(1, i -> i + 1)).limit(10).zip(list, (e1, e2) -> e1 + "." + e2).toList(); Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), zip); }