简体   繁体   中英

Getting a Stream of objects based on value of other member object

I have a Java class of type Project which contains Map of type Process and class Process subsequently contains Map of type 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
    }

I'm trying to write a function which will return a Stream of Process or Process.path where the Process contains at least one activity having type="starter" ie Activity.type="starter" .

I came up with the below code but it returns a Stream<Activity> whereas what I'm looking for is a Stream<Process> or Stream<String> containing the path .

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

What is the most efficient way of doing this?

Don't use flatMap if you want a Stream<Process> because flatMap will "destroy" information about the processes.

You should create a "nested" stream:

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

Now it's a Stream<Process> .

The code given will map the processes to activities via the .flatMap operator.

The operator You are looking for is probably .filter if I understand correcly the request of

I'm trying to write a function which will return a Stream of Process or Process.path where the Process contains at least one activity having type="starter" ie Activity.type="starter".

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

You can then map to Project.path via a .map operator. Given the previous operation as processStream , we might write

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

It may be worth to note that, if the list of activities may be finite, the .findFirst terminal operation may be substituted for a .count terminal operation. It all depends on the clarity of the code, and the speed requirements of the code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM