Gatherers 的方法

windowFixed(windowSize)

将 Stream 的元素分组到固定大小的窗口中。返回的每个窗口 List 是不可修改的。

import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;

public class G1 {
    public static void main(String[] args) {
        List<List<Integer>> windows =
                Stream.of(1, 2, 3, 4, 5, 6, 7, 8).gather(Gatherers.windowFixed(3)).toList();
        System.out.println(windows);
		// 窗口不能修改,会抛异常 UnsupportedOperationException
        windows.get(0).add(1);
    }
}

输出:

[[1, 2, 3], [4, 5, 6], [7, 8]]
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
	at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:147)
	at org.example.stream.G1.main(G1.java:13)

windowSliding(windowSize)

滑动窗口

import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;

public class G2 {
    public static void main(String[] args) {
        List<List<Integer>> windows2 =
                Stream.of(1,2,3,4,5,6,7,8).gather(Gatherers.windowSliding(2)).toList();
        System.out.println(windows2);

        List<List<Integer>> windows6 =
                Stream.of(1,2,3,4,5,6,7,8).gather(Gatherers.windowSliding(6)).toList();
        System.out.println(windows6);
    }
}

输出

[[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8]]
[[1, 2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8]]

fold(initial, folder)

public static <T, R> Gatherer<T, ?, R> fold(
        Supplier<R> initial,
        BiFunction<? super R, ? super T, ? extends R> folder);

类似 reduce 的功能,只会将最后的结果发送到 Stream 的下一个阶段,伪代码如下:

public static <T, R> void fold(Supplier<R> initial, BiFunction<? super R, ? super T, ? extends R> folder) {

    List<T> elements = null;
    R value = initial.get();

    for (T e : elements) {
        value = folder.apply(value, e);
    }

    // 将 value 发送到 Stream 的下一个阶段
}
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import java.util.stream.Gatherers;
import java.util.stream.Stream;

public class G3 {
    public static void main(String[] args) {
        Optional<String> numberString =
                Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
                        .gather(
                                Gatherers.fold(() -> "", (string, number) -> string + number)
                        )
                        .findFirst();
        System.out.println(numberString);
    }
}

// 输出
Optional[123456789]

scan(initial, scanner)

public static <T, R> Gatherer<T, ?, R> scan(
        Supplier<R> initial,
        BiFunction<? super R, ? super T, ? extends R> scanner);

使用提供的 scanner 执行 Prefix Scan – 增量累积。从 initial 获得的初始值开始,通过将 scanner 应用于当前值和下一个输入元素来获取每个后续值,并将每个后续值发送到 Stream 的下一个阶段。

foldscan 的参数是相同的,区别在于 fold 只会将最后的结果发送到下一个阶段,而 scan 会将每个中间结果都发送到下一个阶段。伪代码:

public static <T, R> void scan(Supplier<R> initial, BiFunction<? super R, ? super T, ? extends R> folder) {

    List<T> elements = null;
    R value = initial.get();

    for (T e : elements) {
        value = folder.apply(value, e);
        // 将 value 发送到 Stream 的下一个阶段
    }
}
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import java.util.stream.Gatherers;
import java.util.stream.Stream;

public class G4 {
    public static void main(String[] args) {
        List<String> numberStrings =
                Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
                        .gather(
                                Gatherers.scan(() -> "", (string, number) -> string + number)
                        )
                        .toList();
        System.out.println(numberStrings);
    }
}
// 输出
[1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789]

mapConcurrent(mapConcurrent, mapper)

使用虚拟线程以配置的最大并发级数执行与 Stream#map 方法类似的功能。此操作将保留流的顺序。

public static <T, R> Gatherer<T,?,R> mapConcurrent(
        final int maxConcurrency,
        final Function<? super T, ? extends R> mapper) 
import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;

public class G5 {
    public static void main(String[] args) {
        List<Integer> numberStrings =
                Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
                        .gather(
                                Gatherers.mapConcurrent(3, (element) -> {
                                    System.out.println(Thread.currentThread().isVirtual());
                                    return element * element;
                                })
                        )
                        .toList();
        System.out.println(numberStrings);
    }
}

输出:可以看出确实使用了虚拟线程

true
true
true
true
true
true
true
true
true
[1, 4, 9, 16, 25, 36, 49, 64, 81]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值