当前位置: 首页 > 面试题库 >

Java 8中有与Scala等效的Either吗?

慕俊迈
2023-03-14
问题内容

就像java.util.Optional<T>在Java
8中(某种程度上)等同于Scala的Option[T]类型一样,是否也等同于Scala的类型Either[L, R]


问题答案:

EitherJava 8 没有类型,因此您需要自己创建一个或使用一些第三方库。

您可以使用新Optional类型来构建这样的功能(但请阅读此答案的结尾):

final class Either<L,R>
{
    public static <L,R> Either<L,R> left(L value) {
        return new Either<>(Optional.of(value), Optional.empty());
    }
    public static <L,R> Either<L,R> right(R value) {
        return new Either<>(Optional.empty(), Optional.of(value));
    }
    private final Optional<L> left;
    private final Optional<R> right;
    private Either(Optional<L> l, Optional<R> r) {
      left=l;
      right=r;
    }
    public <T> T map(
        Function<? super L, ? extends T> lFunc,
        Function<? super R, ? extends T> rFunc)
    {
        return left.<T>map(lFunc).orElseGet(()->right.map(rFunc).get());
    }
    public <T> Either<T,R> mapLeft(Function<? super L, ? extends T> lFunc)
    {
        return new Either<>(left.map(lFunc),right);
    }
    public <T> Either<L,T> mapRight(Function<? super R, ? extends T> rFunc)
    {
        return new Either<>(left, right.map(rFunc));
    }
    public void apply(Consumer<? super L> lFunc, Consumer<? super R> rFunc)
    {
        left.ifPresent(lFunc);
        right.ifPresent(rFunc);
    }
}

用例示例:

new Random().ints(20, 0, 2).mapToObj(i -> (Either<String,Integer>)(i==0?
  Either.left("left value (String)"):
  Either.right(42)))
.forEach(either->either.apply(
  left ->{ System.out.println("received left value: "+left.substring(11));},
  right->{ System.out.println("received right value: 0x"+Integer.toHexString(right));}
));

回顾起来,Optional基于基础的解决方案更像是一个学术实例,而不是推荐的方法。一个问题是对null“空” 的处理,这与“任一个”的含义相矛盾。

以下代码显示了一个Either考虑null可能值的,因此即使值是,它也严格是“左右”(左或右)null

abstract class Either<L,R>
{
    public static <L,R> Either<L,R> left(L value) {
        return new Either<L,R>() {
            @Override public <T> T map(Function<? super L, ? extends T> lFunc,
                                       Function<? super R, ? extends T> rFunc) {
                return lFunc.apply(value);
            }
        };
    }
    public static <L,R> Either<L,R> right(R value) {
        return new Either<L,R>() {
            @Override public <T> T map(Function<? super L, ? extends T> lFunc,
                                       Function<? super R, ? extends T> rFunc) {
                return rFunc.apply(value);
            }

        };
    }
    private Either() {}
    public abstract <T> T map(
      Function<? super L, ? extends T> lFunc, Function<? super R, ? extends T> rFunc);

    public <T> Either<T,R> mapLeft(Function<? super L, ? extends T> lFunc) {
        return this.<Either<T,R>>map(t -> left(lFunc.apply(t)), t -> (Either<T,R>)this);
    }
    public <T> Either<L,T> mapRight(Function<? super R, ? extends T> lFunc) {
        return this.<Either<L,T>>map(t -> (Either<L,T>)this, t -> right(lFunc.apply(t)));
    }
    public void apply(Consumer<? super L> lFunc, Consumer<? super R> rFunc) {
        map(consume(lFunc), consume(rFunc));
    }
    private <T> Function<T,Void> consume(Consumer<T> c) {
        return t -> { c.accept(t); return null; };
    }
}

null只需Objects.requireNonNull(value)在两个工厂方法的开头插入,就很容易将其更改为严格拒绝。同样,可以想象增加对空容器的支持。



 类似资料:
  • 本文向大家介绍Scala Either,包括了Scala Either的使用技巧和注意事项,需要的朋友参考一下 示例 错误/成功的不同数据类型 在任何一个值上进行模式匹配 将任一值转换为选项            

  • 就像Java 8中的(在某种程度上)与Scala的类型等价一样,是否存在与Scala的等价的类型?

  • 问题内容: Scala与Java的静态块等效吗? 问题答案: 伴随对象的构造函数(即主体)中的代码与Java类的静态初始化程序块中的代码 不 完全相同。在下面的示例中,我创建了A的实例,但是没有发生初始化。 要在创建类的第一个实例时触发伴随对象的构造,可以从类构造函数中访问它。 在许多情况下,差异并不重要。但是,如果您要发射导弹(或其他副作用),您可能会在意!

  • 问题内容: 在我日常使用Java进行的工作中,我为流畅的接口使用了大量构建器,例如: 使用快捷方法Java,每个方法调用都会更改构建器实例并返回。一成不变的是,它涉及更多的类型输入,在修改之前先克隆构建器。构建方法最终会在构建器状态上进行繁重的工作。 在Scala中实现相同目标的一种好方法是什么? 如果我想,以确保被称为只有一次,随后只和可称为,一拉定向建设者,我怎么会去接近这个? 问题答案: S

  • 问题内容: 在将算法从JavaScript移植到Java时,我遇到了需要替换JavaScript的toPrecision()的问题。问题是我不知道数字的大小是多少,所以我不能使用具有正确格式的简单NumberFormat。 是否有提供类似功能的标准类? 编辑这是我想出的: 原则上,它做对了,但是舍入错误完全毁了它。例如, 返回 编辑2此版本非常适合12个测试用例中的11个… 但是仍然返回而不是 问

  • 问题内容: 在Scala中,我们可以编写 编译器如何实现?我可以从Java 拨打电话,但从Java发出错误 JVM是否本地支持单例? Java中是否可能有没有构造函数的类? 注意:这是代码输出 问题答案: 对单例的支持 不在语言级别上,但是该语言提供了足够的功能来创建它们而没有任何麻烦。 考虑以下代码: 这是来自Wikipedia的示例,该示例说明了如何制作单例。实例保存在私有字段中,在类外部无法