Java8 streams : Filter data from two list of command object. Is there any other efficient way of what i am doing?

Viewed 94

I have two lists that hold WorkflowCommands and WorkflowInstanceCommands.

public List<WorkflowCommand> workflowList = new ArrayList<>();
public List<WorkflowInstanceCommand> workflowInstanceList = new ArrayList<>();

public class WorkflowCommand {

  int id;
  String name;
  String author;
  int version;

  @Override
  public String toString() {
    return "WorkflowCommand{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", author='" + author + '\'' +
            ", version=" + version +
            '}';
  }

}



public class WorkflowInstanceCommand {

  long id;
  int workflowId;
  String assignee;
  String step;
  String status;

  @Override
  public String toString() {
    return "WorkflowInstanceCommand{" +
            "id=" + id +
            ", workflowId=" + workflowId +
            ", assignee='" + assignee + '\'' +
            ", step='" + step + '\'' +
            ", status='" + status + '\'' +
            '}';
  }
}

Need to print out above two results

  1. Find all the workflows with their according Workflow instances.

  2. Find all workflows having running instances and the number of those Workflow instances.

Code for first query:

workflowList.forEach(w -> {
    System.out.println("==workflow data=="+w);
    workflowInstanceList.stream()
            .filter(wi -> w.getId() == wi.getWorkflowId())
            .forEach(System.out::println);
});

Code for second query:

workflowList.forEach(w -> {
    List<WorkflowInstanceCommand> instanceCommands = workflowInstanceList.stream()
        .filter(wi -> w.getId() == wi.getWorkflowId())
        .filter(wi -> wi.getStatus().equals("RUNNING"))
        .collect(Collectors.toList());

    System.out.println("==workflow data=="+w+"===size=="+instanceCommands.size());
    instanceCommands.forEach(System.out::println);
});

Is there any other efficient way of doing it?

1 Answers
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toMap;

First query:

Map<WorkflowCommand, List<WorkflowInstanceCommand>> instancesByWorkflow =
    workflowInstanceList.stream()
        .collect(groupingBy(WorkflowInstanceCommand::getWorkflowId))
        .entrySet().stream()
        .collect(toMap(e -> workflowList.get(e.getKey()), Map.Entry::getValue));

Second query:

Map<WorkflowCommand, Integer> numberOfRunningInstancesByWorkflow =
    .collect(
        toMap(
            e -> e.getKey(),
            e -> e.getValue().stream().filter(i -> i.getStatus().equals("RUNNING")).count()
        )
    );

and if you want to exclude WorkflowCommand with 0 instances you have to add this line to the second query:

.entrySet().stream()
    .filter(e -> e.getValue() != 0)
    .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
Related