Преобразовать поток списка <Object>в поток всех объектов в списке - PullRequest
2 голосов
/ 25 апреля 2020

Следующие лямбда-выражения принимают значения HashMap, получают список объектов в своем ArrayList, добавляют все такие объекты в другой ArrayList и затем распечатывают каждый атрибут, если выполняется условие.

Это работает , но я немного расстроен, я не мог понять, как сделать это за один шаг, например, без использования двух лямбда-выражений.

Map<Integer, Person> people = new HashMap<Integer, Person>();
...
List<Object> objects = new ArrayList<Object>();

people.values().stream()
    .map(p->p.getObjects())
    .forEach(p->objects.addAll(p)); //note: can be multiple
objects.stream()
    .filter(p->p.getClass().toString().contains("Keyword"))
    .forEach(p->System.out.println(p.display()));

Так есть ли способ, которым я могу go напрямую перейти от строки 2 к строке 5, которая фактически преобразует поток списка объектов в поток всех самих объектов?

1 Ответ

1 голос
/ 25 апреля 2020

Вы можете объединить свои операции в один конвейер потока как

List<Pet> cats = people.values().stream()
        .flatMap(p -> p.getPets().stream())
        .filter(p -> p.getClass().toString().contains("Cat")) // or Cat.class::isInstance
        .collect(Collectors.toList());

, а затем выполнять операции над ними, как в вашем коде, например

cats.forEach(cat -> System.out.println(cat.getName()));

Общее преобразование вашего кода будет выглядеть так:

Map<Integer, Person> people = ...;
people.values().stream()
        .flatMap(p -> p.getPets().stream())
        .filter(p -> p.getClass().toString().contains("Cat"))
        .forEach(cat -> System.out.println(cat.getName()));
...