为了简化我的问题,假设我有一个字符串列表,当把这些字符串转换为整数时,我可能会遇到以下情况 NumberFormatException
,从我得到这个异常的元素,我需要把所有的后续元素标记为失败一次。有没有更好的方法来传递前一个元素的状态或者改进这个代码?
AtomicBoolean isInvalidRequest = new AtomicBoolean(false);
list.stream().map(ele -> {
if (!isInvalidRequest.get()) {
try {
Integer.parseInt(ele);
} catch (NumberFormatException e) {
isInvalidRequest = new AtomicBoolean(true);
}
return ele;
} else {
return "invalid previous element";
}
});
给定一个元素列表 List("1", "2", "A", "4", "3")
元素的例外输出 List("1", "2", "A", "invalid previous element", "invalid previous element")
如前所述,这是我实际问题的简化版本。在实际的问题中,我的失败是HTTP POST调用,我需要失败所有随之而来的元素,从元素中我得到一个错误响应。
在无效的元素后改变元素,这是一个奇怪的要求。后果是,当只有最后一个元素无效时,根本就没有变化。
通常情况下,你会对第一个无效元素的索引感兴趣,比如说,你会对第一个无效元素的索引感兴趣。
OptionalInt firstInvalid = IntStream.range(0, list.size())
.filter(ix -> {
try {
Integer.parseInt(list.get(ix));
return false;
} catch (NumberFormatException e) {
return true;
}
})
.findFirst();
然后,如果你真的想以所述方式改变列表,你可以使用
firstInvalid.ifPresent(ix ->
list.subList(ix+1, list.size()).replaceAll(s -> "invalid previous element"));
请注意,这种关注点的分离使得代码更有效率。对第一个无效索引的搜索是短路的,在找到第一个无效元素后返回,而不是处理后续元素。然后无条件地将后续元素设置为预定义值。当所有元素都有效时,第一步必须检查所有元素,但是,第二步就完全跳过了。
我使用了这段代码
AtomicBoolean isInvalidRequest = new AtomicBoolean(false);
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("A");
list.add("4");
list.add("5");
boolean val = false;
List<String> newList = list.stream().map(ele -> {
if(!isInvalidRequest.get()) {
try{
Integer.parseInt(ele);
return ele;
} catch (Exception e) {
isInvalidRequest.set(true);
return "string wrong";
}
} else {
return "previous string wrong";
}
})
.collect(Collectors.toList());
newList.stream().forEach(ele -> System.out.println(ele));
产出是
1
2
string wrong
previous string wrong
previous string wrong
但请记住,从地图函数里面改变状态或产生副作用不是一个好主意。所以你可能要改变这一点。