2016-04-27 6 views
1

私はそれぞれが日付を表す文字列のリストを持っています。このリストをDateTimeオブジェクトのリストにマップしたいと思います。しかし、文字列のいずれかが無効な場合(例外をスローする)、私はエラーを記録したいが、最後のリストには追加しない。同時にフィルタリングとマッピングの両方を行う方法はありますか?同時にJavaストリームをフィルタリングしてマップする

これは私が現在持っているものです。

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

は、私は、各要素のために二回parseDateTimeする必要がないようにこれを行う方法はありますか?

ありがとうございました

答えて

2

最初に文字列を解析された日付にマッピングできます。無効な日付文字列がある場合は、それを記録し、nullを返します。

次に、2番目の手順では、NULL以外の日付をフィルタリングします。

0

逆の順序で操作してください。

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

ここではすべてを単一操作で行うことができます。 Tagirのソリューションと同様にJavaの9

ため

0

更新は、あなたは変換が値を生成するために失敗したときにエラーをログに記録する、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(...); 
関連する問題