问题
Suppose you run an SQL query against an employees table:
SELECT department, team, MIN(salary), MAX(salary)
FROM employees
GROUP BY department, team
And in the java client you map the result set to a list of Aggregate
instances by making a DAO call like below:
List<Aggregate> deptTeamAggregates = employeeDao.getMinMaxSalariesByDeptAndTeam()
And 'Aggregate' has getter methods for department, team, minSalary, maxSalary and there is a Pair<T, T>
tuple
What would be the clearest and possible the most optimal way to map the result set into the two maps below:
Map<String, Pair<Integer, Integer>> byDepartmentMinMax = ...
Map<Pair<String, String>, Pair<Integer, Integer>> byDepartmentAndTeamMinMax = ...
I know I could map my result set in a different way and/or make two trips to the database and achieve the same thing in an easier way but I am more about understanding the java 8 capabilities.
Thank you in advance for your inputs.
回答1:
class Pair<T, U> {
public final T x;
public final U y;
public Pair(T x, U y) {
this.x = x;
this.y = y;
}
}
Collector<Aggregate, ?, Pair<Integer, Integer>> aggregateSalary =
mapping(a -> new Pair<>(a.getMinSalary(), a.getMaxSalary()),
reducing(new Pair<>(Integer.MAX_VALUE, Integer.MIN_VALUE),
(a, b) -> new Pair<>(Math.min(a.x, b.x), Math.max(a.y, b.y))));
Map<String, Pair<Integer, Integer>> byDepartmentMinMax =
deptTeamAggregates.stream()
.collect(groupingBy(a -> a.getDepartment(), aggregateSalary));
Map<Pair<String, String>, Pair<Integer, Integer>> byDepartmentAndTeamMinMax =
deptTeamAggregates.stream()
.collect(toMap(a -> new Pair<>(a.getDepartment(), a.getTeam()), a -> new Pair<>(a.getMinSalary(), a.getMaxSalary())));
来源:https://stackoverflow.com/questions/30958516/java-8-stream-group-by-min-and-max