同时过滤和映射java流

Nos*_*tap 4 java datetime dictionary filter java-stream

我有一个字符串列表,每个字符串代表一个日期.我想将此列表映射到DateTime对象列表中; 但是,如果任何字符串无效(抛出异常)我想记录错误但不将其添加到最终列表中.有没有办法同时进行过滤和映射?

这就是我目前拥有的:

List<String> dateStrs = ...;
dateStrs.stream().filter(s -> {
    try {
        dateTimeFormatter.parseDateTime(s);
        return true;
    } catch (Exception e) {
        log.error("Illegal format");
        return false;
    }
}.map(s -> {
    return dateTimeFormatter.parseDateTime(s);
}.collect(...);
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点,所以我不必为每个元素parseDateTime两次?

谢谢

Tag*_*eev 6

在我看来,flatMap在这里使用会更加惯用:

dateStrs.stream().flatMap(s -> {
    try {
        return Stream.of(dateTimeFormatter.parseDateTime(s));
    } catch (Exception e) {
        return Stream.empty();
    }
}).collect(...);
Run Code Online (Sandbox Code Playgroud)

在这里,您可以一次性完成所有操作.


AJN*_*eld 5

更新 Java 9

与 Tagir 的解决方案类似,您可以映射到Optional,在转换无法生成值时记录错误。然后,使用新Optional::stream方法,您可以flatMap在可选上从流中删除失败的转换(空可选)。

dateStrs.stream()
    .map(s -> {
        try {
            return Optional.of(dateTimeFormatter.parseDateTime(s));
        } catch (Exception e) {
            log.error("Illegal format: " + s);
            return Optional.empty();
        }
    })
    .flatMap(Optional::stream)
    .collect(...);
Run Code Online (Sandbox Code Playgroud)


wer*_*ero 2

您可以首先将字符串映射到其解析的日期。如果遇到无效的日期字符串,则将其记录下来并返回 null。

然后在第二步中过滤非空日期。