在以下代码中,从NumberFormatException
次迭代中捕获for
时,在第一个错误的strList
之前出现"illegal_3"
的相应形式的字符串(即"1"
)已成功解析(即"2"
和1
已被解析为整数2
和public void testCaughtRuntimeExceptionOutOfIteration() {
List<String> strList = Stream.of("1", "2", "illegal_3", "4", "illegal_5", "6").collect(Collectors.toList());
List<Integer> intList = new ArrayList<>();
try{
for (String str : strList) {
intList.add(Integer.parseInt(str));
}
} catch (NumberFormatException nfe) {
System.err.println(nfe.getMessage());
}
List<Integer> expectedIntList = Stream.of(1, 2).collect(Collectors.toList());
// passed
assertEquals("The first two elements have been parsed successfully.", expectedIntList, intList);
}
)。
for
但是,当stream()
或parallelStream()
替换1
次迭代时,我会失去2
和public void testCaughtRuntimeExceptionOutOfStream() {
List<String> strList = Stream.of("1", "2", "illegal_3", "4", "illegal_5", "6").collect(Collectors.toList());
List<Integer> intList = new ArrayList<>();
try{
intList = strList.stream() // same with "parallelStream()"
.map(Integer::parseInt)
.collect(Collectors.toList());
} catch (NumberFormatException nfe) {
System.err.println(nfe.getMessage());
}
List<Integer> expectedIntList = Stream.of(1, 2).collect(Collectors.toList());
// failed: expected:<[1,2]>, but was:<[]>
assertEquals("The first two elements have been parsed successfully.", expectedIntList, intList);
}
。
stream()
parallelStream()
或intList = [1,2]
内引发的异常控制流程的规范是什么?如何获得
NumberFormatException
的结果(即忽略第一个intList = [1,2,4,6]
之后的结果)或更好NumberFormatException
(即忽略stream()
的结果parallelStream()
1}})CREATE SCHEMA
或SQLDBSAMPLE
答案 0 :(得分:8)
为什么不在try...catch
中包裹lambda-body?
您也可以在null
之后过滤map
个值:
intList = strList.stream()// same with "parallelStream()"
.map(x -> {
try {
return Integer.parseInt(x);
} catch (NumberFormatException nfe) {
System.err.println(nfe.getMessage());
}
return null;
})
.filter(x -> x!= null)
.collect(Collectors.toList());
这将为您提供所需的intList = [1,2,4,6]
。
编辑:减少&#34;沉重&#34;在lamdba中的try / catch中,您可以添加辅助方法。
static Integer parseIntOrNull(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException nfe) {
System.err.println(nfe.getMessage());
}
return null;
}
intList = strList.stream()
.map(x -> parseIntOrNull(x))
.filter(x -> x!= null)
.collect(Collectors.toList());
或者为避免使用null,您可以返回Stream
static Stream<Integer> parseIntStream(String s) {
try {
return Stream.of(Integer.parseInt(s));
} catch (NumberFormatException nfe) {
System.err.println(nfe.getMessage());
}
return Stream.empty();
}
intList = strList.stream()
.flatMap(x -> parseIntStream(x))
.collect(Collectors.toList());
答案 1 :(得分:2)
方法既不能返回值,也不能抛出异常。那是不可能的。
因此,您不能指望collect()
返回列表并抛出异常。因为如果抛出异常,它就不能返回新的列表。
如果您的for循环代码实际上与流代码类似,那么您将遇到同样的问题:
public void testCaughtRuntimeExceptionOutOfIteration() {
List<String> strList = Stream.of("1", "2", "illegal_3", "4", "illegal_5", "6").collect(Collectors.toList());
List<Integer> intList = new ArrayList<>();
try{
intList = collectToIntegers(strList);
} catch (NumberFormatException nfe) {
System.err.println(nfe.getMessage());
}
List<Integer> expectedIntList = Stream.of(1, 2).collect(Collectors.toList());
// fails
assertEquals("The first two elements have been parsed successfully.", expectedIntList, intList);
}
private List<Integer> collectToIntegers(List<String> strList) {
List<Integer> result = new ArrayList<>();
for (String str : strList) {
result.add(Integer.parseInt(str));
}
return result;
}
简而言之:不要混淆“创建和返回新列表”,“获取列表并向其添加元素”。
答案 2 :(得分:1)
我不知道有多少次遇到过我只想忽略NumberFormatException的情况。我可能会创建一个单独的可重用方法来静默解析整数并返回OptionalInt值。
这是utils类
public class IntUtils {
// ... other utility methods
public static OptionalInt parseInt(String s, Consumer<? super Exception> exceptionConsumer) {
try {
return OptionalInt.of(Integer.parseInt(s));
} catch (NumberFormatException e) {
if (exceptionConsumer != null) {
// let the caller take the decision
exceptionConsumer.accept(e);
} else {
// default behavior
e.printStackTrace();
}
}
return OptionalInt.empty();
}
public static OptionalInt parseInt(String s) {
return parseInt(s, null);
}
}
这是测试方法
List<Integer> collect1 = strStream.map(str -> IntUtils.parseInt(str, Exception::printStackTrace))
.filter(OptionalInt::isPresent)
.map(OptionalInt::getAsInt).collect(toList());
// or
List<Integer> collect2 = strStream.map(IntUtils::parseInt)
.filter(OptionalInt::isPresent)
.map(OptionalInt::getAsInt).collect(toList());
答案 3 :(得分:0)
我正在使用org.apache.commons.lang3.math.NumberUtils
:
.mapToInt(s -> NumberUtils.toInt(s, Integer.MIN_VALUE))
.filter(x -> x > Integer.MIN_VALUE)