-3

How can I re-write the below nested for loop with conditions using java stream and lambda ?

for (String taskInit : initialTaskStatus.keySet()) {
            for (String taskFin : finalTaskStatus.keySet()) {
                if (!(taskInit.equalsIgnoreCase(taskFin)))
                    continue;
                else {
                    if (initialTaskStatus.get(taskInit).equalsIgnoreCase("COMPLETE") ||
                            initialTaskStatus.get(taskInit).equalsIgnoreCase("CANCELLED")) {
                        //Do something (1)

                    } else if (initialTaskStatus.get(taskInit).equalsIgnoreCase("IN_PROGRESS")) {
                        //Do something (2)
                    }
                }

            }
        }
User
  • 7
  • 7
  • 4
    Why must you rewrite it with streams? – Sweeper Apr 14 '20 at 12:39
  • Aside from main question: why `if (!condition){ continue; }else{ someJob(); }` instead of `if(condition){ someJob(); }` which in your case is equivalent to `if(condition){ someJob(); }else{ continue; }` since there is no other code aside from that `if` inside loop? – Pshemo Apr 14 '20 at 12:44

4 Answers4

0

Hope this helps.

   initialTaskStatus.keySet().forEach(taskInit -> {
        finalTaskStatus.keySet().stream().filter(taskInit::equalsIgnoreCase).forEach(taskFin -> {
            if (initialTaskStatus.get(taskInit).equalsIgnoreCase("COMPLETE") ||
                    initialTaskStatus.get(taskInit).equalsIgnoreCase("CANCELLED")) {
                //Do something (1)

            } else if (initialTaskStatus.get(taskInit).equalsIgnoreCase("IN_PROGRESS")) {
                //Do something (2)
            }
        });
    });
Binu
  • 754
  • 6
  • 15
0

The task class was not provided so for this example i'm assuming it as a String. All you have to do is collect all keys from the final map that exist in the initial map if they have the same status. You can collect to a List and then operate after.

        Map<String, String> initialTaskStatus = new HashMap<>();

        Map<String, String> finalTaskStatus = new HashMap<>();

        List<String> tasks = initialTaskStatus.keySet().stream()
                .filter(initialTask -> finalTaskStatus.keySet()
                        .stream().anyMatch(finalTask -> finalTask.equalsIgnoreCase(initialTask)))
                .collect(Collectors.toList());

        List<String> completeOrCancelled = tasks.stream()
                .filter(task -> task.equalsIgnoreCase("COMPELTE") || task.equalsIgnoreCase("CANCELLED"))
                .collect(Collectors.toList());

        List<String> inProgress = tasks.stream()
                .filter(task -> task.equalsIgnoreCase("IN_PROGRESS"))
                .collect(Collectors.toList());

        completeOrCancelled.forEach(task -> System.out.println("Complete or cancelled!"));
        inProgress.forEach(task -> System.out.println("In progress!"));
Jason
  • 5,154
  • 2
  • 12
  • 22
0

I think that nested forEach loops may not be needed here, so the following snippet including an extracted method to handle status should do this job:

    initialTaskStatus.entrySet().stream()
        .filter(e -> finalTaskStatus.containsKey(e.getKey()))
        .forEach(e -> handleStatus(e.getValue().toUpperCase()));
    ...

    private void handleStatus(String status) {
        if ("COMPLETE".equals(status) || "CANCELLED".equals(status)) {
            //Do something (1)
        } else if ("IN_PROGRESS".equals(status)) {
            //Do something (2)
        }
    }
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
0

This is something that I would do:

List<String> status = Arrays.asList("COMPLETE", "CANCELED");
    String IN_PROGRESS = "IN_PROGRESS";

    initialTaskStatus.keySet().forEach(taskInit -> finalTaskStatus.keySet().forEach(taskFin ->{
        if (status.contains(initialTaskStatus.get(taskInit).toUpperCase())) {
            //Do something (1)

        } else if (IN_PROGRESS.equals(initialTaskStatus.get(taskInit).toUpperCase())) {
            //Do something (2)
        }
    }));