在下面的代码中,当从 for
迭代中捕获 NumberFormatException
时,适当形式的字符串出现在 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);
}
但是,当用 stream()
或 parallelStream()
替换 for
迭代时,我丢失了 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);
}
What is the specification of the control flow of exceptions thrown from within
stream()
orparallelStream()
?How can I get the result of
intList = [1,2]
(i.e., ignore the ones after the firstNumberFormatException
is thrown) or even betterintList = [1,2,4,6]
(i.e., ignore the bad ones withNumberFormatException
) withstream()
orparallelStream()
最佳答案
为什么不将 lambda 体包裹在 try...catch
中?
您还可以在 map
之后过滤 null
值:
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]
。
编辑:要减少 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());
关于java - 从 'stream()' 或 'parallelStream()' 中捕获异常会丢失正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34564025/