![](/img/trans.png)
[英]How can we customize order of count,avg,sum,min and max in DoubleSummaryStatistics object in java8
[英]Return in one string the min, max, average, sum, count of salaries with Stream and java8
我有一份以薪水為特征的雇員List
。 為什么此代碼不起作用?
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(", "));
我正在使用一套收集器。
請注意,當前您嘗試獲取的不是最高/最低薪水,而是擁有該薪水的雇員。 如果您實際上想獲得最高/最低工資本身(數字),則可以使用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(", "));
如果您確實想獲得薪水最高/最低的Employee,則此處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()));
我終於找到了解決方案。。謝謝嘗試的家伙
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}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.