根据其他成员对象的值获取对象流

时间:2019-03-19 16:39:52

标签: java java-stream

我有一个Project类型的Java类,其中包含Process类型的Map,而Process类随后包含了Activity类型的Map。

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
    }

我正在尝试编写一个函数,该函数将返回StreamProcess的{​​{1}},其中Process.path包含至少一个具有Process的活动即type="starter"

我想到了下面的代码,但是它返回了Activity.type="starter",而我正在寻找的是包含Stream<Activity>的{​​{1}}或Stream<Process>

Stream<String>

最有效的方法是什么?

2 个答案:

答案 0 :(得分:2)

如果要使用flatMap,请不要使用Stream<Process>,因为flatMap将“破坏”有关进程的信息。

您应该创建一个“嵌套”流:

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

现在是Stream<Process>

答案 1 :(得分:1)

给出的代码将通过.flatMap运算符将流程映射到活动。

如果我正确理解以下要求,您正在寻找的运算符可能是.filter

  

我正在尝试编写一个函数,该函数将返回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终端操作。这完全取决于代码的清晰度和代码的速度要求。