定义either类

在我们日常开发中,stream流里面如果出现了异常是没法直接抛出的,需要进行try-catch进行捕获然后进行处理,或者干脆直接抛出异常停止

这个时候我们需要一个either工具类,区分成功和失败的执行结果,并且单独对失败的这些结果进行处理,以下是一些简单的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.tthk.inland.ticket.core.utils.stream;

import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* @Description either类
* @date 2023/4/20_15:05
* @author Foam
*/
public class Either<L, R> {
public static void main(String[] args) {
List<EitherUtil<String,String>> collect = Stream.iterate(1, i -> i + 1).limit(100).map(Either::readline).collect(Collectors.toList());
EitherUtil<String, List<String>> sequence = EitherUtil.sequence(collect, (s1, s2) -> s1 + s2);
if(sequence.isLeft()){
System.out.println(sequence.getLeft());
}else{
List<String> right = sequence.getRight();
for (String s : right) {
System.out.println(s);
}
}
}

public static EitherUtil<String,String> readline(int i){
if((new Random().nextInt() %2) >= 0){
return EitherUtil.right("成功");
}else {
return EitherUtil.left("错误");
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.tthk.inland.ticket.core.utils.stream;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @Description either工具类
* @date 2023/4/20_15:12
* @author Foam
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EitherUtil<L,R> {
/**
* @Description 异常数据
* @date 2023/4/20
**/
private L left;
/**
* @Description 正常数据
* @date 2023/4/20
**/
private R right;

public boolean isLeft(){
return left != null;
}

public boolean isRight(){
return right != null;
}

/**
* @Description 工厂方法 - 左值
* @date 2023/4/20
**/
public static <L,R> EitherUtil<L,R> left(L exception){
EitherUtil<L,R> e = new EitherUtil<L,R>();
e.left = exception;
return e;
}

/**
* @Description 工厂方法 - 右值
* @date 2023/4/20
**/
public static <L,R> EitherUtil<L,R> right(R value){
EitherUtil<L,R> e = new EitherUtil<L,R>();
e.right = value;
return e;
}

/**
* @Description map方法,如果是异常值,进行保存,如果是正常值,进行函数映射
* @date 2023/4/20
**/
public <T> EitherUtil<L,T> map(Function<R,T> function){
if(isLeft()){
return left(left);
}else {
return right(function.apply(right));
}
}

/**
* @Description 将either的list转换成一个either对象,里面分别装正常值和异常值
* @date 2023/4/20
**/
public static <L,R> EitherUtil<L, List<R>> sequence(List<EitherUtil<L,R>> eitherList, BinaryOperator<L> accumulator){
if(eitherList.stream().allMatch(EitherUtil::isRight)){
// 将所有数据存入
return right(eitherList.stream().map(EitherUtil::getRight).collect(Collectors.toList()));
}else {
// 结合需求,确定是取第一个异常还是取全部异常
// 1.取第一个异常
// return left(eitherList.stream().filter(EitherUtil::isLeft).findFirst().orElseThrow().getLeft());
// 2.取全部异常
return left(eitherList.stream().filter(EitherUtil::isLeft).map(EitherUtil::getLeft).reduce(accumulator).orElseThrow());
}
}

/**
* @Description 获取所有的异常数据
* @date 2023/4/20
**/
public static <L,R> EitherUtil<L, List<R>> sequenceLift(List<EitherUtil<L,R>> eitherList, BinaryOperator<L> accumulator){
return left(eitherList.stream().filter(EitherUtil::isLeft).map(EitherUtil::getLeft).reduce(accumulator).orElseThrow());
}
}