Можно ли привести поток в Java 8? Скажем, у меня есть список объектов, я могу сделать что-то вроде этого, чтобы отфильтровать все дополнительные объекты:
Stream.of(objects).filter(c -> c instanceof Client)
Однако после этого, если я хочу что-то сделать с клиентами, мне нужно разыграть каждого из них:
Stream.of(objects).filter(c -> c instanceof Client)
.map(c -> ((Client) c).getID()).forEach(System.out::println);
Это выглядит немного некрасиво. Можно ли привести весь поток к другому типу? Как бросить Stream<Object>
к Stream<Client>
?
Пожалуйста, игнорируйте тот факт, что подобные вещи, вероятно, означают плохой дизайн. Мы занимаемся такими вещами на моем уроке информатики, поэтому я изучал новые функции Java 8 и мне было любопытно, возможно ли это.
java
java-8
java-stream
Phiction
источник
источник
Ответы:
Я не думаю, что есть способ сделать это из коробки. Возможно более чистое решение было бы:
или, как предлагается в комментариях, вы можете использовать
cast
метод - первый может быть легче читать, хотя:источник
map
вернет aStream<Client>
. Спасибо!Stream.of(objects).filter(Client.class::isInstance).[...]
В соответствии с ответом ggovan я делаю это следующим образом:
Используя эту вспомогательную функцию:
источник
Поздно на вечеринку, но я думаю, что это полезный ответ.
flatMap
был бы самый короткий способ сделать это.Если
o
это,Client
то создайте поток с одним элементом, в противном случае используйте пустой поток. Эти потоки будут затем сплющены вStream<Client>
.источник
if/else
вместо?:
оператора, то не было бы никакого предупреждения. Будьте уверены, что вы можете безопасно подавить предупреждение.Stream.of(objects).filter(o->o instanceof Client).map(o -> (Client)o)
дажеStream.of(objects).filter(Client.class::isInstance).map(Client.class::cast)
.Нет, это было бы невозможно. Это не ново в Java 8. Это характерно для дженериков. А
List<Object>
не супер типList<String>
, так что вы не можете просто привестиList<Object>
кList<String>
.Подобная проблема здесь. Вы не можете бросить
Stream<Object>
наStream<Client>
. Конечно, вы можете использовать его косвенно следующим образом:но это небезопасно и может дать сбой во время выполнения. Основная причина этого заключается в том, что дженерики в Java реализованы с использованием стирания. Таким образом, нет никакой доступной информации о типе того, какой
Stream
это тип во время выполнения. Все простоStream
.Кстати, что не так с вашим подходом? Выглядит хорошо для меня.
источник
C#
реализован с использованием reification, в то время как в Java он реализован с использованием стирания. Оба реализованы по-разному в основе. Таким образом, вы не можете ожидать, что он будет работать одинаково на обоих языках.