我设法使用Java 8 Streams API编写解决方案,该解决方案首先按对象组合对象Route列表,然后计算每个组中对象的数量。它返回一个映射Route - > Long。以下是代码:
I have managed to write a solution using Java 8 Streams API that first groups a list of object Route by its value and then counts the number of objects in each group. It returns a mapping Route -> Long. Here is the code:
Map<Route, Long> routesCounted = routes.stream() .collect(Collectors.groupingBy(gr -> gr, Collectors.counting()));和Route类:
public class Route implements Comparable<Route> { private long lastUpdated; private Cell startCell; private Cell endCell; private int dropOffSize; public Route(Cell startCell, Cell endCell, long lastUpdated) { this.startCell = startCell; this.endCell = endCell; this.lastUpdated = lastUpdated; } public long getLastUpdated() { return this.lastUpdated; } public void setLastUpdated(long lastUpdated) { this.lastUpdated = lastUpdated; } public Cell getStartCell() { return startCell; } public void setStartCell(Cell startCell) { this.startCell = startCell; } public Cell getEndCell() { return endCell; } public void setEndCell(Cell endCell) { this.endCell = endCell; } public int getDropOffSize() { return this.dropOffSize; } public void setDropOffSize(int dropOffSize) { this.dropOffSize = dropOffSize; } @Override /** * Compute hash code by using Apache Commons Lang HashCodeBuilder. */ public int hashCode() { return new HashCodeBuilder(43, 59) .append(this.startCell) .append(this.endCell) .toHashCode(); } @Override /** * Compute equals by using Apache Commons Lang EqualsBuilder. */ public boolean equals(Object obj) { if (!(obj instanceof Route)) return false; if (obj == this) return true; Route route = (Route) obj; return new EqualsBuilder() .append(this.startCell, route.startCell) .append(this.endCell, route.endCell) .isEquals(); } @Override public int compareTo(Route route) { if (this.dropOffSize < route.dropOffSize) return -1; else if (this.dropOffSize > route.dropOffSize) return 1; else { // if contains drop off timestamps, order by last timestamp in drop off // the highest timestamp has preceding if (this.lastUpdated < route.lastUpdated) return -1; else if (this.lastUpdated > route.lastUpdated) return 1; else return 0; } } }我还想要什么实现是每个组的密钥将是具有最大lastUpdated值的密钥。我已经在查看此解决方案,但我不知道如何按值计算计数和分组以及路由最大lastUpdated值。以下是我想要实现的示例数据:
What I would like to additionally achieve is that the key for each group would be the one with the largest lastUpdated value. I was already looking at this solution but I do not know how to combine the counting and grouping by value and Route maximum lastUpdated value. Here is the example data of what I want to achieve:
示例:
List<Route> routes = new ArrayList<>(); routes.add(new Route(new Cell(1, 2), new Cell(2, 1), 1200L)); routes.add(new Route(new Cell(3, 2), new Cell(2, 5), 1800L)); routes.add(new Route(new Cell(1, 2), new Cell(2, 1), 1700L));应该转换为:
Map<Route, Long> routesCounted = new HashMap<>(); routesCounted.put(new Route(new Cell(1, 2), new Cell(2, 1), 1700L), 2); routesCounted.put(new Route(new Cell(3, 2), new Cell(2, 5), 1800L), 1);请注意,映射的密钥(计算2个路由)是具有最大lastUpdated的值。
Notice that the key for mapping, which counted 2 Routes is the one with the largest lastUpdated value.
推荐答案这是一种方法。首先将列分组到列表中,然后将列表处理为您实际需要的值:
Here's one approach. First group into lists and then process the lists into the values you actually want:
import static java.util.ComparatorparingLong; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toMap; Map<Route,Integer> routeCounts = routes.stream() .collect(groupingBy(x -> x)) .values().stream() .collect(toMap( lst -> lst.stream().max(comparingLong(Route::getLastUpdated)).get(), List::size ));更多推荐
按对象值分组,计数,然后按最大对象属性设置组密钥
发布评论