【问题标题】:Filter and map a java stream at the same time同时过滤和映射一个java流
【发布时间】:2016-08-22 05:38:30
【问题描述】:

我有一个字符串列表,每个字符串代表一个日期。我想将此列表映射到 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(...);

有什么办法可以让我不必为每个元素解析两次日期时间?

谢谢

【问题讨论】:

    标签: java datetime dictionary filter java-stream


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      以相反的顺序进行操作。

      List<String> dateStrs = ...;
      dateStrs.stream().map(s -> {
          try {
              return dateTimeFormatter.parseDateTime(s);
          } catch (Exception e) {
              return null;
          }
      }).filter(d -> d != null).collect(...);
      

      (我意识到这与@wero 本质上相同,但为时已晚,但希望代码能够清楚地说明。)

      【讨论】:

        【解决方案3】:

        在我看来,在这里使用flatMap 会更符合习惯用法:

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

        在这里您可以一次操作完成所有操作。

        【讨论】:

          【解决方案4】:

          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(...);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-03-29
            • 2016-03-27
            • 2017-12-22
            • 2021-09-02
            • 2022-01-18
            • 1970-01-01
            • 2017-01-20
            相关资源
            最近更新 更多