2016-03-02 4 views
33

У меня есть следующее выражение:Java 8 поток - проверить, если InstanceOf

scheduleIntervalContainers.stream() 
     .filter(sic -> ((ScheduleIntervalContainer)sic).getStartTime() != ((ScheduleIntervalContainer)sic).getEndTime()) 
     .collect(Collectors.toList()); 

где scheduleIntervalContainers имеет тип ScheduleContainer

final List<ScheduleContainer> scheduleIntervalContainers 

Есть ли вешать проверки типа перед фильтром?

ответ

43

Вы можете применить другой filter для того, чтобы сохранить только ScheduleIntervalContainer экземпляров, и добавление map сэкономит вам позже слепки:

scheduleIntervalContainers.stream() 
    .filter(sc -> sc instanceof ScheduleIntervalContainer) 
    .map (sc -> (ScheduleIntervalContainer) sc) 
    .filter(sic -> sic.getStartTime() != sic.getEndTime()) 
    .collect(Collectors.toList()); 
+59

Или '.filter (ScheduleIntervalContainer.class :: isInstance) .map (ScheduleIntervalContainer.class :: cast)', независимо от стиля, который вы предпочитаете. – Holger

56

Довольно элегантный вариант заключается в использовании метода ссылки класса:

scheduleIntervalContainers 
    .stream() 
    .filter(ScheduleIntervalContainer.class::isInstance) 
    .map(ScheduleIntervalContainer.class::cast) 
    .filter(sic -> sic.getStartTime() != sic.getEndTime()) 
    .collect(Collectors.toList()); 
9

Существует небольшая проблема с @Eran решением - набрав имя класса в обоих filter и map является подверженными ошибкам - это легко забыть сп ange имя класса в обоих местах. Улучшенное решение было бы что-то вроде этого:

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

Смежные вопросы