2015-12-15 59 views
-1

我有一個List僱員的特點是工資。 爲什麼這段代碼不起作用?返回一個字符串中的最小值,最大值,平均值,總和,流和java8的工資計數

String joined = employees.stream().collect(
    Collectors.summingInt(Employee::getSalary), 
    Collectors.maxBy(Comparator.comparing(Employee::getSalary)), 
    Collectors.minBy(Comparator.comparing(Employee::getSalary)), 
    Collectors.averagingLong((Employee e) ->e.getSalary() * 2), 
    Collectors.counting(), 
    Collectors.joining(", ")); 

我正在使用一套收集器。

+2

有沒有這樣的方法,需要在你想要做的多個收藏家 - 你可能有一個編譯錯誤。花一些時間閱讀[這個流教程](http://www.oracle.com/technetwork/articles/java/architect-streams-pt2-2227132.html) – Krease

+1

請閱讀[問] –

+1

當我回答時,我不得不猜猜你想得到什麼。如果您提供了期望的結果示例,則您的問題將更加清晰。 –

回答

0

我終於找到了解決辦法..謝謝對於試圖傢伙

String s = employees.stream().mapToDouble(a>a.getSalary()).summaryStatistics().toString(); 

,這是輸出:

DoubleSummaryStatistics{count=21, sum=17200,000000, min=100,000000, 
average=819,047619, max=2100,000000} 
+0

請注意,您的解決方案解決了不同的問題。至少把平均數乘以2是什麼? –

3

請注意,目前您正試圖獲取最高/最低工資,但員工擁有此類工資。如果你確實想擁有的最大/最小工資本身(數字),那麼這些特性可以在使用一次Collectors.summarizingInt()計算:

IntSummaryStatistics stats = employees.stream() 
    .collect(Collectors.summarizingInt(Employee::getSalary)); 

如果你想將它們加入到字符串,你可以使用:

String statsString = Stream.of(stats.getSum(), stats.getMax(), stats.getMin(), 
           stats.getAverage()*2, stats.getCount()) 
          .map(Object::toString) 
          .collect(Collectors.joining(", ")); 

如果你真的想要得到與最大/最小工資的員工,這裏IntSummaryStatistics不會幫你。但是您可以創建收藏家的流來代替:

String result = Stream.<Collector<Employee,?,?>>of(
      Collectors.summingInt(Employee::getSalary), 
      Collectors.maxBy(Comparator.comparing(Employee::getSalary)), 
      Collectors.minBy(Comparator.comparing(Employee::getSalary)), 
      Collectors.averagingLong((Employee e) ->e.getSalary() * 2), 
      Collectors.counting()) 
     .map(collector -> employees.stream().collect(collector)) 
     .map(Object::toString) 
     .collect(Collectors.joining(", ")); 

注意,這樣你就會有一個像輸出(取決於Employee.toString()實現:

1121, Optional[Employee [salary=1000]], Optional[Employee [salary=1]], 560.5, 4 

不要忘記,maxBy/minBy返回Optional


如果您不滿意該第一溶液和某種原因唐「噸要遍歷多次輸入,就可以使用這樣的方法創建一個組合收藏家:

/** 
* Returns a collector which joins the results of supplied collectors 
* into the single string using the supplied delimiter. 
*/ 
@SafeVarargs 
public static <T> Collector<T, ?, String> joining(CharSequence delimiter, 
     Collector<T, ?, ?>... collectors) { 
    @SuppressWarnings("unchecked") 
    Collector<T, Object, Object>[] cs = (Collector<T, Object, Object>[]) collectors; 
    return Collector.<T, Object[], String>of(
     () -> Stream.of(cs).map(c -> c.supplier().get()).toArray(), 
     (acc, t) -> IntStream.range(0, acc.length) 
      .forEach(idx -> cs[idx].accumulator().accept(acc[idx], t)), 
     (acc1, acc2) -> IntStream.range(0, acc1.length) 
      .mapToObj(idx -> cs[idx].combiner().apply(acc1[idx], acc2[idx])) 
      .toArray(), 
     acc -> IntStream.range(0, acc.length) 
      .mapToObj(idx -> cs[idx].finisher().apply(acc[idx]).toString()) 
      .collect(Collectors.joining(delimiter))); 
} 

有這樣的方法,你可以寫

String stats = employees.stream().collect(joining(", ", 
     Collectors.summingInt(Employee::getSalary), 
     Collectors.maxBy(Comparator.comparing(Employee::getSalary)), 
     Collectors.minBy(Comparator.comparing(Employee::getSalary)), 
     Collectors.averagingLong((Employee e) ->e.getSalary() * 2), 
     Collectors.counting())); 
+1

我認爲,'IntSummaryStatistics'''toString()'方法的輸出比'statsString'更有用。雖然平均值不是平均值的兩倍,但爲什麼你會將平均值加倍...... – Holger

+1

@Holger,可能是這樣。這個問題真的很奇怪。 –

+0

謝謝你回答@TagirValeev ..你部分解決了問題 。事實上,我想要的是返回一個字符串和一行中的最大值,最小值,計數值,平均值和總和。它應該像這樣開始:String joined = employees.stream()。 /*...other方法* /。順便提一下這個奇怪的問題,我在03:00 AM –

相關問題