Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I calculate a percentage based on the output of a Java 8 Stream filter

I want to take a List of jobs (called resultStream) and calculate the percentage of jobs that were completed fully.

public class Job {
    private Date date;
    private String success;

    // Getter and setter and constructor.
}

The list contains the following:

new Job("TODAY", "YES");
new Job("TODAY", "YES");
new Job("YESTERDAY", "YES");
new Job("TODAY", "NO");

Here is the code I have so far:

resultStream.stream().parallel().filter(result -> {
   if ("YES".contains(result.getSuccess())) {
       return true;         
   } else {
       return false;
   }
}).collect(groupingBy(Job::getDate, HashMap::new, counting()));

This returns me a HashMap(Date, Long) with the following:
TODAY, 2
YESTERDAY, 1

I actually want the following result:
TODAY, 66%
YESTERDAY, 100%

Thanks in advance.

like image 447
user3131879 Avatar asked Jul 21 '14 20:07

user3131879


People also ask

How do you calculate a percentage in Java?

Percentage = (Obtained score x 100) / Total Score To get these parameters (inputs) from the user, try using the Scanner function in Java.

How do you calculate 50 percent in Java?

int k = (int)(120 / 100)*50; The above does not work because you are performing an integer division expression (120 / 100) which result is integer 1, and then multiplying that result to 50, giving the final result of 50.


1 Answers

Average as double can be done as so:

public static void main(final String... args) {
    final List<Job> jobs = new ArrayList<>();
    jobs.add(new Job(LocalDate.now(), "YES"));
    jobs.add(new Job(LocalDate.now(), "NO"));
    jobs.add(new Job(LocalDate.now(), "YES"));
    jobs.add(new Job(LocalDate.now()
            .minusDays(1), "YES"));

    final Map<LocalDate, Double> result = jobs.stream()
        .collect(
                    Collectors.groupingBy(Job::getDate,
                            Collectors.mapping(Job::getSuccess, Collectors.averagingDouble(success -> {
                                return "YES".equals(success) ? 1 : 0;
                            }))));

    // result = {2014-07-20=1.0, 2014-07-21=0.6666666666666666}
    System.out.println(result);
}

As strings:

public static void main(final String... args) {
    final List<Job> jobs = new ArrayList<>();
    jobs.add(new Job(LocalDate.now(), "YES"));
    jobs.add(new Job(LocalDate.now(), "NO"));
    jobs.add(new Job(LocalDate.now(), "YES"));
    jobs.add(new Job(LocalDate.now()
            .minusDays(1), "YES"));

    final Map<LocalDate, String> result = jobs.stream()
            .collect(
                    Collectors.groupingBy(
                            Job::getDate,
                            Collectors.collectingAndThen(
                                    Collectors.mapping(Job::getSuccess, Collectors.averagingDouble(success -> {
                                        return "YES".equals(success) ? 1 : 0;
                                    })), avg -> String.format("%,.0f%%", avg * 100))));
    // result = {2014-07-20=100%, 2014-07-21=67%}
    System.out.println(result);
}
like image 69
Jeff Avatar answered Sep 28 '22 01:09

Jeff