Java 中的联合类型

2022-09-02 22:12:21

我已经使用C#一段时间了,并试图更熟悉Java。因此,我正在尝试迁移我每天在C#中使用的一些基本模式,即使只是为了了解JVM和dotnet之间的差距并弄清楚如何处理它们。这是我遇到的第一个问题 - 一个选项类型 - somethiong,在许多语言中很容易实现,即Koltlin:

sealed class Option<out T : Any> {
    object None : Option<Nothing>()
    data class Some<out T : Any>(val value: T) : Option<T>()}

所以我可以很容易地创建一个映射函子:

fun <T : Any, B : Any> Option<T>.map(f: (T) -> B): Option<B> =
    when (this) {
        is Option.None -> Option.None
        is Option.Some -> Option.Some(f(this.value))} 

这是我在Java中可以实现的吗?我不担心缺乏扩展方法,我可以不用它,但是如何在不依赖于未经检查的强制转换的情况下执行实际的类型匹配?至少这就是IntelliJ所抱怨的...


答案 1

在您提到的特定情况下,以下内容将起作用:

Java没有模式匹配。在 Java 中,最接近模式匹配的是访客模式

用法:

UnionType unionType = new TypeA();

Integer count = unionType.when(new UnionType.Cases<Integer>() {
    @Override
    public Integer is(TypeA typeA) {
        // TypeA-specific handling code
    }

    @Override
    public Integer is(TypeB typeB) {
        // TypeB-specific handling code
    }
});

样板代码:

interface UnionType {
    <R> R when(Cases<R> c);

    interface Cases<R> {
        R is(TypeA typeA);

        R is(TypeB typeB);
    }
}

class TypeA implements UnionType {

    // ... TypeA-specific code ...

    @Override
    public <R> R when(Cases<R> cases) {
        return cases.is(this);
    }
}

class TypeB implements UnionType {

    // ... TypeB-specific code ...

    @Override
    public <R> R when(Cases<R> cases) {
        return cases.is(this);
    }
}

答案 2

当我遇到这种情况时,我的函数需要处理或.所以我总是传递两者(将不存在的设置为),并且函数类似于double[]String[]null

public void myFunc(String[] valuesCategorical, double[] valuesNumeric){
    if (valuesCategorical == null){
        doSomethingWithCategorical(valuesCategorical);
    } else {
        doSomethingWithNumeric(valuesNumeric);
    }
}

推荐