public class eithercl<l,r>{
private final l left:
private final r right;
private either(l left, r right){
this left=left;
this right =right;
}
public static <l, r> either,<l,r> left( l value) {
return new either(value, null):
}
public static <l, r> either<l, r> right( r value) {
return new either(null, value)
}
public optional<l> getleft() {
return optional. ofnullable(left)
}
public optional<r> getright() {
return optional.ofnullable(right);
}
public boolean isleft() {
return left i- null;
}
public boolean isright(){
return right != null;
}
public < t> optional<t> mapleft(function<? super l, t> mapper){
if (isleft()) {
return optional of(mapper. apply(left));
}
return optional empty();
}
public <t> optional<t> mapright(function<? super r, t> mapper) {
if (isright()) {
return optional of(mapper. apply(right));
}
return optionalempty();
}
public string tostring(){
if (isleft()){
return"left(”+left+")";
}
return "right("+ right +")";
}
}
现在我们需要再定义一个 lift 函数,该函数内部将 function 函数正常返回的值或者抛出的异常都使用 either 类进行了一层封装
现在我们的代码变成这个样子了,也不用担心方法抛出异常会提前终止 stream 了 优化四: 保留原始值
现在思考一个问题,如果在上述处理过程中,当结果是异常信息的时候,我们想要重试,即重新调用这个方法怎么办? 你会发现我们 either 封装类没有保存最原始的这个值,我们丢掉了原始值,因此我们可以进一步优化,将原始值 t 也封装进 left 字段中,就像下面这样:
pair 类是一个非常简单的封装类,用以封装两个值:
public class pair<f, s> {
public final f fst;
public final s snd;
private pair(f fst, s snd){
this fst fst;
this snd= snd;
}
public static <f, s> pair<f, s> of(f fst, s snd){
return new pair<>(fst, snd);
}
}