Получение потока объектов на основе значения другого объекта-члена - PullRequest
2 голосов
/ 19 марта 2019

У меня есть класс Java типа Project, который содержит карту типа Process, а класс Process впоследствии содержит карту типа Activity.

public class Project {
    private String name;
    private Path path;
    private Map<String, Process> processes;
    //getters and setters
    }

public class Process {
    private String name;
    private String path;
    private Map<String, Activity> activities;
    //getters and setters
    }

public class Activity {
    private String name;
    private String type;
    //getters and setters
    }

Я пытаюсь написать функциюкоторый вернет Stream из Process или Process.path, где Process содержит хотя бы одно действие, имеющее type="starter" т.е. Activity.type="starter".

Я пришел с приведенным ниже кодом, но он возвращаетStream<Activity>, тогда как я ищу Stream<Process> или Stream<String>, содержащий path.

project.processes.values().stream()
    .flatMap(process -> process.getActivities().values().stream()
            .filter(activity -> "starter".equals(activity.getType())));

Какой самый эффективный способ сделать это?

Ответы [ 2 ]

2 голосов
/ 19 марта 2019

Не используйте flatMap, если вы хотите Stream<Process>, потому что flatMap "уничтожит" информацию о процессах.

Вы должны создать "вложенный" поток:

project.getProcesses().values().stream()
        .filter(x -> 
                x.getActivities().values().stream().anyMatch(
                        y -> "starter".equals(y.getType())
                )
        );

Теперь это Stream<Process>.

1 голос
/ 19 марта 2019

Приведенный код отобразит процессы в действия с помощью оператора .flatMap.

Оператор, которого вы ищете, вероятно, .filter, если я правильно понимаю запрос

Я пытаюсь написать функцию, которая будет возвращать Stream of Process или Process.path, где Process содержит хотя бы одно действие, имеющее type = "starter", т.е. Activity.type = "starter".

project.processes.values().stream()
    .filter(process -> process.getActivities().values().stream()
            .filter(activity -> "starter".equals(activity.getType())).findFirst().isPresent());

Затем вы можете отобразить на Project.path с помощью оператора .map. Учитывая предыдущую операцию как processStream, мы могли бы написать

processStream.map(process -> process.getPath())

Стоит отметить, что, если список действий может быть конечным, операция терминала .findFirst может быть заменена операцией терминала .count. Все зависит от ясности кода и требований к скорости кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...