You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Java Stream或Reactor流中连续元素两两配对生成新对象

实现方案

1. Java Stream 实现

Stream本身是无状态的单向迭代结构,原生没有直接提供相邻元素配对的能力,分两种场景实现:

1.1 有限有序流原生实现

如果你的流是有限、有序的,最简单的方式是先转成列表再按索引配对:

// 你的日期流
Stream<LocalDate> dateStream = Stream.of(LocalDate.of(2024,1,1), LocalDate.of(2024,1,2), LocalDate.of(2024,1,3));
// 定义配对对象,Java 16+可用record,低版本用普通类即可
record DatePair(LocalDate prev, LocalDate curr) {}

List<LocalDate> dateList = dateStream.toList();
Stream<DatePair> pairStream = IntStream.range(0, dateList.size() - 1)
        .mapToObj(i -> new DatePair(dateList.get(i), dateList.get(i + 1)));

注意:该方案仅适用于有限流,无限流调用toList()会永久阻塞。不要在map中用外部临时变量存储上一个元素的方式实现,并行流场景下会有线程安全问题。

1.2 通用实现(支持无限流/并行流)

可以用增强Stream库StreamEx的内置pairMap方法实现,适配所有场景:

Stream<DatePair> pairStream = StreamEx.of(dateStream)
        .pairMap(DatePair::new);

2. Reactor Flux 实现

Reactor内置了相邻元素操作的能力,推荐两种写法:

2.1 推荐方案:zipWith + skip

该写法性能更高,无多余计算:

Flux<LocalDate> dateFlux = Flux.just(LocalDate.of(2024,1,1), LocalDate.of(2024,1,2), LocalDate.of(2024,1,3));
record DatePair(LocalDate prev, LocalDate curr) {}

Flux<DatePair> pairFlux = dateFlux
        .zipWith(dateFlux.skip(1), DatePair::new);

2.2 缓存窗口实现

用buffer操作创建步长为1、大小为2的窗口,过滤掉最后不足2个元素的窗口即可:

Flux<DatePair> pairFlux = dateFlux
        .buffer(2, 1)
        .filter(list -> list.size() == 2)
        .map(list -> new DatePair(list.get(0), list.get(1)));

内容的提问来源于stack exchange,提问作者Shubhankar Agrawal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 07:24:00