![](/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.