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

如何为Java中ImmutablePair创建支持String/Double的联合类型

解决方案:实现支持String/Double联合类型的参数列表

针对你的需求,我们可以通过以下几种方式在Java中实现类似联合类型(Sum Type)的结构,替换原有的List<ImmutablePair<Integer, String>>:

方案1:Java 16+ 密封类(Sealed Classes)实现类型安全的联合类型

密封类是Java 16引入的特性,天生适合定义联合类型,能在编译时确保所有类型分支都被处理,避免遗漏。

步骤1:定义密封接口作为联合类型

// 密封接口,限定只能由指定的子类实现
public sealed interface ParamValue permits ParamValue.StringValue, ParamValue.DoubleValue {
    // 内部记录类,存储String类型值
    record StringValue(String value) implements ParamValue {}
    // 内部记录类,存储Double类型值
    record DoubleValue(Double value) implements ParamValue {}
}

步骤2:修改列表类型

将原有的列表类型替换为:

List<ImmutablePair<Integer, ParamValue>> params;

步骤3:使用时的类型处理

通过switch表达式(Java 14+)可以安全地处理两种类型,编译器会检查是否覆盖了所有分支:

for (ImmutablePair<Integer, ParamValue> pair : params) {
    Integer key = pair.getKey();
    ParamValue value = pair.getValue();
    
    String output = switch (value) {
        case ParamValue.StringValue sv -> String.format("Key %d: String值 - %s", key, sv.value());
        case ParamValue.DoubleValue dv -> String.format("Key %d: Double值 - %.2f", key, dv.value());
    };
    
    System.out.println(output);
}

方案2:兼容Java 16之前版本的标记接口方案

如果你的项目还在使用Java 16以下的版本,可以用标记接口+实现类的方式模拟联合类型:

步骤1:定义标记接口和实现类

// 标记接口,作为String/Double类型的共同父类
public interface ParamValue {}

// 存储String值的实现类
public class StringParam implements ParamValue {
    private final String value;
    
    public StringParam(String value) {
        this.value = value;
    }
    
    public String getValue() {
        return value;
    }
}

// 存储Double值的实现类
public class DoubleParam implements ParamValue {
    private final Double value;
    
    public DoubleParam(Double value) {
        this.value = value;
    }
    
    public Double getValue() {
        return value;
    }
}

步骤2:修改列表类型

同样替换为:

List<ImmutablePair<Integer, ParamValue>> params;

步骤3:使用时的类型处理

通过instanceof关键字判断类型,需要手动确保覆盖所有可能的实现类:

for (ImmutablePair<Integer, ParamValue> pair : params) {
    Integer key = pair.getKey();
    ParamValue value = pair.getValue();
    
    if (value instanceof StringParam stringParam) {
        System.out.printf("Key %d: String值 - %s%n", key, stringParam.getValue());
    } else if (value instanceof DoubleParam doubleParam) {
        System.out.printf("Key %d: Double值 - %.2f%n", key, doubleParam.getValue());
    } else {
        throw new IllegalArgumentException("不支持的参数类型: " + value.getClass().getName());
    }
}

方案3:自定义不可变Pair类(替代commons-lang3的ImmutablePair)

如果不想依赖第三方库,可以自己实现一个专门的不可变Pair类,封装联合类型的创建逻辑,让代码更简洁:

public sealed interface ParamValue permits ParamValue.StringValue, ParamValue.DoubleValue {
    record StringValue(String value) implements ParamValue {}
    record DoubleValue(Double value) implements ParamValue {}
}

// 自定义不可变参数Pair类
public final class ImmutableParamPair {
    private final Integer key;
    private final ParamValue value;

    private ImmutableParamPair(Integer key, ParamValue value) {
        this.key = key;
        this.value = value;
    }

    // 静态工厂方法,直接创建String类型的参数对
    public static ImmutableParamPair ofString(Integer key, String value) {
        return new ImmutableParamPair(key, new ParamValue.StringValue(value));
    }

    // 静态工厂方法,直接创建Double类型的参数对
    public static ImmutableParamPair ofDouble(Integer key, Double value) {
        return new ImmutableParamPair(key, new ParamValue.DoubleValue(value));
    }

    public Integer getKey() {
        return key;
    }

    public ParamValue getValue() {
        return value;
    }
}

此时列表类型变为:

List<ImmutableParamPair> params;

使用时无需手动创建StringValue或DoubleValue实例,直接调用工厂方法:

params.add(ImmutableParamPair.ofString(1, "username"));
params.add(ImmutableParamPair.ofDouble(2, 99.99));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:43:14