2014-07-21 61 views
4

我想獲取作業列表(稱爲resultStream)並計算完全完成的作業百分比。如何計算基於Java 8 Stream過濾器輸出的百分比

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

    // Getter and setter and constructor. 
} 

列表包含以下內容:

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

這裏是我的代碼至今:

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

這將返回我一個HashMap(日期,龍)具有以下內容:
今天,2
昨天1

其實我是想了以下結果:
今天,66%
YESTERDAY,100%

在此先感謝。

+2

BTW您的過濾器實際上應該說'結果 - > 「YES」。載有(result.getSuccess() )' –

回答

7

平均爲雙可以爲這樣做:

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); 
} 

作爲字符串:

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); 
} 
+1

+1對我來說很不錯。平均一個[指標函數](http://en.wikipedia.org/wiki/Indicator_function)是與這些布爾值類似的方法。 –

+2

+1,我希望有人會證明我錯了:)順便說一句,你可以用'averagingDouble'中的表達式代替lambda塊。 –

+0

這段代碼是爲你編譯的嗎?我在IntelliJ中得到一個錯誤,說「avg」是一個對象,而運算符「*」不能應用於avg。 – user3131879