使用Lamdad表达式时,会调用一些方法,这些方法可能会抛出异常,但是在Lambad中异常必须捕获再抛出,有没有一种方法记录异常并返回呢,在做导入功能是,我们需要记录导入了哪些数据,哪些数据有问题,如果直接在Lamdad中捕获就会导致遇到异常程序就终止执行抛出异常,下面我们看一种方法.
1. 创建记录数据类
@Data
public class Either<L,R> {
/**
* 代表异常数据
*/
private L left;
/**
* 代表正常数据
*/
private R right;
public boolean isLeft(){
return this.left != null;
}
public boolean isRight(){
return this.right != null;
}
/**
* 添加异常值
*/
public static <L,R> Either<L,R> left(L exception){
Either<L,R> either = new Either<>();
either.setLeft(exception);
return either;
}
/**
* 添加正常值
*/
public static <L,R> Either<L,R> right(R value){
Either<L,R> either = new Either<>();
either.setRight(value);
return either;
}
public <T> Either<L,T> map(Function<R,T> function){
if(isRight()){
return right(function.apply(right));
}else{
return left(left);
}
}
public static <L,R> Either<L,List<R>> sequence(List<Either<L,R>> eitherList, BinaryOperator<L> operator){
if(eitherList.stream().allMatch(Either::isRight)){
return right(eitherList.stream().map(Either::getRight).collect(Collectors.toList()));
}
return left(eitherList.stream()
.filter(Either::isLeft)
.map(Either::getLeft)
.reduce(operator)
.orElseThrow(null)
);
}
}
3. 使用
public class Test {
public static void main(String[] args) {
List<Either<String,User>> list = IntStream.rangeClosed(1,100)
.mapToObj(line -> {
return readLine(line);
}).collect(Collectors.toList());
//list.forEach(System.out::println);
Either<String, List<User>> listEither = Either.sequence(list, (s1,s2) -> {
return s1 + "\n" + s2;
});
System.out.println(listEither.getLeft());
}
/**
* 模拟读取指定行的数据
* @param line
* @return
*/
public static Either<String, User> readLine(int line){
if(new SecureRandom().nextInt(100) <= 50){
return Either.right(new User("zs"+1,20));
}else{
return Either.left("第"+line+"行数据错误");
}
}
}
@Data
@AllArgsConstructor
class User{
private String name;
private Integer age;
}
输出结果如下: