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));}
));
8条答案
按热度按时间mtb9vblg1#
Java 8中没有
Either
类型,因此您需要自己创建一个或使用一些第三方库。您可以使用新的
Optional
类型构建这样的功能(但请阅读本答案的结尾):示例用例:
回顾过去,基于
Optional
的解决方案更像是一个学术示例,但不是推荐的方法。一个问题是将null
视为“空”,这与“任一”的含义相矛盾。下面的代码显示了一个
Either
,它认为null
是一个可能的值,所以它是严格的“要么”,左或右,即使值是null
:很容易将其更改为严格拒绝
null
,只需在两个工厂方法的开头插入Objects.requireNonNull(value)
。同样,添加对空either的支持也是可以想象的。xam8gpfp2#
在撰写本文时,vavr(以前的javaslang)可能是最流行的Java 8函数库。这是非常相似的lambda-companion的要么在我的另一个答案。
jecbmhm33#
Java标准库中没有Either。然而,在FunctionalJava中有Either的实现,沿着许多其他不错的类。
ie3xauqp4#
cyclops-react有一个“右”偏置的实现,称为Xor。
还有一个相关的类型Ior,它可以充当either或tuple 2。
a2mppw5e5#
不,没有。
Java语言开发人员明确指出,像
Option<T>
这样的类型只打算用作临时值(例如在流操作结果中),所以虽然它们与其他语言中的东西是一样的,但它们不应该像其他语言中使用的那样被使用。因此,不存在Either
这种东西并不奇怪,因为它不是自然产生的(例如从流操作),如Optional
所做的。cotxawn76#
在一个小库中有一个
Either
的独立实现,“ambivalence”:http://github.com/poetix/ambivalence您可以从Maven Central获得:
htzpubme7#
lambda-companion有一个
Either
类型(以及一些其他功能类型,例如Try
)使用它很容易:
kyks70gy8#
**注意:**有关以下
Either
类的增强和完整文档版本(包括equals
、hashCode
、flatMap
和其他杂项帮助函数),请访问this Gist。我采用了@Holger在他的(目前投票最高的)Answer中提供的实现,并对其进行了一些改进,以消除我能找到的所有
null
问题。我将它重构为与OpenJKD更加一致的命名约定。
然后我通读了评论,并进行了调整和调整,以进一步提高实施的质量。
我还在构造函数中添加了状态验证,并添加了两个辅助方法:
isLeft()
、isRight()
、getLeft()
和getRight()
。**注意:**有关以下
Either
类的增强和完整文档版本(包括equals
、hashCode
、flatMap
和其他杂项帮助函数),请访问this Gist。