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

就像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)在两个工厂方法的开头插入,就很容易将其更改为严格拒绝。同样,可以想象增加对空容器的支持。

以上是 Java 8中有与Scala等效的Either吗? 的全部内容, 来源链接: utcz.com/qa/407809.html

回到顶部