У меня есть такое выражение:
scheduleIntervalContainers.stream()
.filter(sic -> ((ScheduleIntervalContainer) sic).getStartTime() != ((ScheduleIntervalContainer)sic).getEndTime())
.collect(Collectors.toList());
... где scheduleIntervalContainers
есть тип элемента ScheduleContainer
:
final List<ScheduleContainer> scheduleIntervalContainers
Можно ли перед фильтром проверить тип?
.filter(ScheduleIntervalContainer.class::isInstance) .map(ScheduleIntervalContainer.class::cast)
любом другом стиле.List<ScheduleContainer>
или aList<ScheduleIntervalContainer>
? Это должно быть последнее.Довольно элегантный вариант - использовать ссылку на метод класса:
источник
.class
нужно? не являетсяisInstance
частьюObject
? ЭтоClass
класс на Java?ScheduleIntervalContainer
не будет экземпляром.Существует небольшая проблема с @ Эран решение - имя класса набрав в обоих
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источник
select(A.class)
вернетnull
все, что не являетсяA
. Добавление.filter(Objects::nonNull)
поможет. Кстати: подход @Eran нулевой.flatMap
говорит: "Если отображаемый поток равен нулю, вместо этого используется пустой поток.". Итак, ваше решение было правильным, даже без нулевого фильтра.null
когда вы могли только что вернуть пустой поток