Java中的联合类型

vlurs2pr  于 2022-12-17  发布在  Java
关注(0)|答案(2)|浏览(186)

我已经用C#工作了一段时间,并试图更熟悉Java。所以我试图迁移一些基本的模式,我每天使用的C#,甚至只是为了了解JVM和dotnet之间差距,并找出如何处理它们。这里是我遇到的第一个问题-一个选项类型-这是很容易实现的许多语言,如Koltlin:

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

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

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抱怨的...

bvjxkvbb

bvjxkvbb1#

在你提到的具体情况下,以下做法可行:

  • (正如@oldcurmudgeon提到的)java.util.Optional它也有一个map函数。
  • 这里还有guava库,它有com.google.common.base.Optional,如果你想在java版本7和更低版本中使用它的话。这里map的等价物是transform函数。

Java没有模式匹配,在Java中最接近模式匹配的是the visitor pattern
用法:

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);
    }
}
gudnpqoy

gudnpqoy2#

当我遇到这种情况时,我的函数需要处理double[]String[],所以我总是同时传递这两个函数(将不存在的设置为null),函数如下所示

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

相关问题