mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
:trollface: 增强EasyStream#zip对并行流的支持,提供CollectorUtil.entryToMap对Entry转map提供支持,完善javadoc
This commit is contained in:
parent
b7d924b34d
commit
492a281cf9
@ -361,4 +361,14 @@ public class CollectorUtil {
|
||||
return transform(ArrayList::new, mapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于{@code Stream<Entry>} 转 Map 的情况
|
||||
*
|
||||
* @param <K> key类型
|
||||
* @param <V> value类型
|
||||
* @return map
|
||||
*/
|
||||
public static <K, V> Collector<Map.Entry<K, V>, ?, Map<K, V>> entryToMap() {
|
||||
return toMap(Map.Entry::getKey, Map.Entry::getValue);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import java.util.stream.Stream;
|
||||
*
|
||||
* @param <T> 流中的元素类型
|
||||
* @param <S> {@link TerminableWrappedStream}的实现类类型
|
||||
* @author huangchengxing
|
||||
* @author huangchengxing VampireAchao
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T, S>> extends WrappedStream<T, S> {
|
||||
@ -451,6 +451,7 @@ public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T,
|
||||
*
|
||||
* @param predicate 判断条件
|
||||
* @param collFactory 提供的集合
|
||||
* @param <C> 集合类型
|
||||
* @return map
|
||||
* @see #partition(Predicate, Collector)
|
||||
*/
|
||||
|
@ -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 <T> 流中的元素类型
|
||||
* @param <S> {@link TransformableWrappedStream}的实现类类型
|
||||
* @author huangchengxing
|
||||
* @author huangchengxing VampireAchao
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface TransformableWrappedStream<T, S extends TransformableWrappedStream<T, S>> extends WrappedStream<T, S> {
|
||||
@ -43,21 +42,12 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
|
||||
final Iterable<U> other,
|
||||
final BiFunction<? super T, ? super U, ? extends R> zipper) {
|
||||
Objects.requireNonNull(zipper);
|
||||
final Spliterator<T> keys = spliterator();
|
||||
final Spliterator<U> 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<R> list = new ArrayList<>(sizeIfKnown);
|
||||
// 保存第一个Spliterator的值
|
||||
final MutableObj<T> key = new MutableObj<>();
|
||||
// 保存第二个Spliterator的值
|
||||
final MutableObj<U> value = new MutableObj<>();
|
||||
// 当两个Spliterator中都还有剩余元素时
|
||||
while (keys.tryAdvance(key::set) && values.tryAdvance(value::set)) {
|
||||
list.add(zipper.apply(key.get(), value.get()));
|
||||
Map<Integer, T> idxIdentityMap = mapIdx((e, idx) -> MapUtil.entry(idx, e)).collect(CollectorUtil.entryToMap());
|
||||
Map<Integer, U> 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)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,15 +181,15 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
|
||||
}
|
||||
|
||||
/**
|
||||
* <<p>删除流中与断言匹配的元素,当遇到第一个不匹配的元素时终止,返回由剩余不匹配的元素组成的流。<br>
|
||||
* 删除流中与断言匹配的元素,当遇到第一个不匹配的元素时终止,返回由剩余不匹配的元素组成的流。
|
||||
* eg:
|
||||
* <pre>{@code
|
||||
* EasyStream.of(1, 2, 3, 4, 5)
|
||||
* .dropWhile(i -> !Objects.equals(3, i)) // 删除不为3的元素,一直到遇到第一个3为止
|
||||
* .toList(); // = [3, 4, 5]
|
||||
* }</pre>
|
||||
*
|
||||
* <p>与{@code JDK9}中的{@code dropWhile}方法不太一样,此操作为顺序且有状态的中间操作。
|
||||
* <p>
|
||||
* 与{@code JDK9}中的{@code dropWhile}方法不太一样,此操作为顺序且有状态的中间操作。
|
||||
* 即使在并行流中,该操作仍然是顺序执行的,并且不影响后续的并行操作:
|
||||
* <pre>{@code
|
||||
* EasyStream.iterate(1, i -> i + 1)
|
||||
@ -261,6 +251,7 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
|
||||
/**
|
||||
* 返回与指定函数将元素作为参数执行后组成的流。操作带下标,并行流时下标永远为-1
|
||||
* 这是一个无状态中间操作
|
||||
*
|
||||
* @param action 指定的函数
|
||||
* @return 返回叠加操作后的FastStream
|
||||
* @apiNote 该方法存在的意义主要是用来调试
|
||||
|
@ -98,8 +98,8 @@ public class AbstractEnhancedWrappedStreamTest {
|
||||
@Test
|
||||
public void testFindFirst() {
|
||||
final List<Integer> 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<Integer> 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<Integer> 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,9 +312,9 @@ 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
|
||||
@ -328,12 +328,12 @@ public class AbstractEnhancedWrappedStreamTest {
|
||||
|
||||
@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
|
||||
@ -613,7 +613,7 @@ public class AbstractEnhancedWrappedStreamTest {
|
||||
|
||||
@Test
|
||||
public void testToEntries() {
|
||||
final Map<Integer, Integer> expect = new HashMap<Integer, Integer>(){{
|
||||
final Map<Integer, Integer> expect = new HashMap<Integer, Integer>() {{
|
||||
put(1, 1);
|
||||
put(2, 2);
|
||||
put(3, 3);
|
||||
@ -636,7 +636,7 @@ public class AbstractEnhancedWrappedStreamTest {
|
||||
List<String> zip = wrap(orders).zip(list, (e1, e2) -> e1 + "." + e2).toList();
|
||||
Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), zip);
|
||||
|
||||
zip = wrap((Stream<? extends Object>)EasyStream.iterate(1, i -> i + 1)).zip(list, (e1, e2) -> e1 + "." + e2).toList();
|
||||
zip = wrap((Stream<? extends Object>) 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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user