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

如何通过一次Stream操作获取集合中对象的两个去重字段集合

一次Stream操作获取去重的VehicleType和regCode集合

要通过单次Stream遍历得到去重的VehicleType集合和regCode集合,可以根据Java版本选择不同的实现方式:

方案一:使用Java 12+的Collectors.teeing(推荐)

teeing收集器允许在一次流处理中同时应用两个下游收集器,最后合并结果,完美匹配需求:

首先确保Vehicle类有对应的getter方法:

class Vehicle {
    VehicleType type;
    String regCode;

    public VehicleType getType() {
        return type;
    }

    public String getRegCode() {
        return regCode;
    }
}

enum VehicleType {
    CAR, BUS
}

然后执行Stream操作:

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair; // 也可使用其他Pair实现,比如javafx.util.Pair

List<Vehicle> vehicles = List.of(
    new Vehicle() {{ type = VehicleType.CAR; regCode = "AB11"; }},
    new Vehicle() {{ type = VehicleType.BUS; regCode = "XY12"; }},
    new Vehicle() {{ type = VehicleType.CAR; regCode = "AB22"; }},
    new Vehicle() {{ type = VehicleType.BUS; regCode = "AB22"; }}
);

Pair<Set<VehicleType>, Set<String>> result = vehicles.stream()
    .collect(Collectors.teeing(
        // 第一个收集器:提取并去重VehicleType
        Collectors.mapping(Vehicle::getType, Collectors.toSet()),
        // 第二个收集器:提取并去重regCode
        Collectors.mapping(Vehicle::getRegCode, Collectors.toSet()),
        // 合并两个结果为Pair
        Pair::of
    ));

// 输出结果示例:Pair{left=[CAR, BUS], right=[AB11, XY12, AB22]}
System.out.println(result);

方案二:自定义收集容器(兼容Java 8及以上)

如果使用Java版本低于12,可以自定义一个收集容器,在单次遍历中同时收集两种数据:

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.tuple.Pair;

// 自定义收集容器
class VehicleStats {
    private final Set<VehicleType> types = new HashSet<>();
    private final Set<String> regCodes = new HashSet<>();

    // 累加单个Vehicle数据
    public void accept(Vehicle vehicle) {
        types.add(vehicle.getType());
        regCodes.add(vehicle.getRegCode());
    }

    // 并行流场景下合并多个容器数据
    public VehicleStats merge(VehicleStats other) {
        types.addAll(other.types);
        regCodes.addAll(other.regCodes);
        return this;
    }

    // 转换为需求的Pair格式
    public Pair<Set<VehicleType>, Set<String>> toPair() {
        return Pair.of(types, regCodes);
    }
}

// 执行Stream操作
Pair<Set<VehicleType>, Set<String>> result = vehicles.stream()
    .collect(
        VehicleStats::new,
        VehicleStats::accept,
        VehicleStats::merge
    ).toPair();

两种方案都仅遍历一次Stream,满足“一次Stream操作”的要求,最终结果与预期格式一致。

内容的提问来源于stack exchange,提问作者Abbin Varghese

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 19:28:33