私は次の式を持っています:
scheduleIntervalContainers.stream()
.filter(sic -> ((ScheduleIntervalContainer) sic).getStartTime() != ((ScheduleIntervalContainer)sic).getEndTime())
.collect(Collectors.toList());
...ここで、scheduleIntervalContainers
の要素タイプはScheduleContainer
です。
final List<ScheduleContainer> scheduleIntervalContainers
フィルターの前にタイプを確認することはできますか?
filter
インスタンスのみを保持するために別のScheduleIntervalContainer
を適用できます。map
を追加すると、後のキャストが保存されます。
scheduleIntervalContainers.stream()
.filter(sc -> sc instanceof ScheduleIntervalContainer)
.map (sc -> (ScheduleIntervalContainer) sc)
.filter(sic -> sic.getStartTime() != sic.getEndTime())
.collect(Collectors.toList());
または、Holgerがコメントしたように、そのスタイルが必要な場合は、ラムダ式をメソッド参照に置き換えることができます。
scheduleIntervalContainers.stream()
.filter(ScheduleIntervalContainer.class::isInstance)
.map (ScheduleIntervalContainer.class::cast)
.filter(sic -> sic.getStartTime() != sic.getEndTime())
.collect(Collectors.toList());
非常にエレガントなオプションは、クラスのメソッド参照を使用することです:
scheduleIntervalContainers
.stream()
.filter( ScheduleIntervalContainer.class::isInstance )
.map( ScheduleIntervalContainer.class::cast )
.filter( sic -> sic.getStartTime() != sic.getEndTime())
.collect(Collectors.toList() );
@ Eran ソリューションに小さな問題があります-filter
とmap
の両方にクラス名を入力するとエラーが発生しやすくなります-クラスの名前を変更するのを忘れがちです両方の場所で。改善されたソリューションは、次のようなものになります。
private static <T, R> Function<T, Stream<R>> select(Class<R> clazz) {
return e -> clazz.isInstance(e) ? Stream.of(clazz.cast(e)) : null;
}
scheduleIntervalContainers
.stream()
.flatMap(select(ScheduleIntervalContainer.class))
.filter( sic -> sic.getStartTime() != sic.getEndTime())
.collect(Collectors.toList());
ただし、一致する要素ごとにStream
を作成すると、パフォーマンスが低下する場合があります。巨大なデータセットで使用するように注意してください。私はこのソリューションを@ Tagir Vailev から学びました