java8 对总和进行流分组和排序
java8 stream grouping and sorting on aggregate sum
给定一个 java class 东西
class Something {
private int parentKey;
private String parentName;
private int childKey;
private int noThings;
public Something(int parentKey, String parentName, int childKey,
int noThings) {
this.parentKey = parentKey;
this.parentName = parentName;
this.childKey = childKey;
this.noThings = noThings;
}
public int getParentKey() {
return this.parentKey;
}
public int getNoThings() {
return this.noThings;
}
}
我有一个对象列表
List<Something> somethings = newArrayList(
new Something(425, "Lemon", 44, 23),
new Something(123, "Orange", 125, 66),
new Something(425, "Lemon", 11, 62),
new Something(123, "Orange", 126, 32),
new Something(323, "Lime", 25, 101),
new Something(123, "Orange", 124, 88)
);
我希望能够对它们进行排序,以便它们按每个父对象的 noThings 的累积总和排序,然后按 noThings 排序。
所以我最终得到
List<Something> sortedSomethings = newArrayList(
new Something(123, "Orange", 124, 88),
new Something(123, "Orange", 125, 66),
new Something(123, "Orange", 126, 32),
new Something(323, "Lime", 25, 101),
new Something(425, "Lemon", 11, 62),
new Something(425, "Lemon", 44, 23)
);
我知道通过 parentKey 和 noThings 的总和来映射它是
Map<Integer, Integer> totalNoThings = colns
.stream()
.collect(
Collectors.groupingBy(
Something::getParentKey,
Collectors.summingInt(ClientCollectionsReceived::getNoThings)));
我认为也许可以包装我的 Something class 并且每个父密钥的总数可能会以某种方式起作用。
class SomethingWrapper {
private int totalNoThingsPerClient;
private Something something;
}
但是看起来工作量很大,不太优雅。
如有任何意见/想法,我们将不胜感激。
好吧,你已经通过收集汇总信息完成了主要工作
Map<Integer, Integer> totalNoThings = somethings.stream()
.collect(Collectors.groupingBy(Something::getParentKey,
Collectors.summingInt(Something::getNoThings)));
那么您需要做的就是在排序操作中利用这些信息:
List<Something> sorted=somethings.stream().sorted(
Comparator.comparing((Something x)->totalNoThings.get(x.getParentKey()))
.thenComparing(Something::getNoThings).reversed())
.collect(Collectors.toList());
实际上不得不做一个小调整,而不是 totalNoThings.get,而是 totalNothings.indexOf
最后的解决方案。是
List<Integer> totalNoThings
= somethings.stream()
.collect(Collectors.groupingBy(Something::getParentKey,
Collectors.summingInt(Something::getNoThings)))
.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.collect(Collectors.toList());
List<Something> sorted
= somethings.stream().sorted(
Comparator.comparing(
(Something obj)->totalNoThings.indexOf(
obj.getParentKey()))
.thenComparing(Something::getNoThings).reversed())
.collect(Collectors.toList());
给定一个 java class 东西
class Something {
private int parentKey;
private String parentName;
private int childKey;
private int noThings;
public Something(int parentKey, String parentName, int childKey,
int noThings) {
this.parentKey = parentKey;
this.parentName = parentName;
this.childKey = childKey;
this.noThings = noThings;
}
public int getParentKey() {
return this.parentKey;
}
public int getNoThings() {
return this.noThings;
}
}
我有一个对象列表
List<Something> somethings = newArrayList(
new Something(425, "Lemon", 44, 23),
new Something(123, "Orange", 125, 66),
new Something(425, "Lemon", 11, 62),
new Something(123, "Orange", 126, 32),
new Something(323, "Lime", 25, 101),
new Something(123, "Orange", 124, 88)
);
我希望能够对它们进行排序,以便它们按每个父对象的 noThings 的累积总和排序,然后按 noThings 排序。
所以我最终得到
List<Something> sortedSomethings = newArrayList(
new Something(123, "Orange", 124, 88),
new Something(123, "Orange", 125, 66),
new Something(123, "Orange", 126, 32),
new Something(323, "Lime", 25, 101),
new Something(425, "Lemon", 11, 62),
new Something(425, "Lemon", 44, 23)
);
我知道通过 parentKey 和 noThings 的总和来映射它是
Map<Integer, Integer> totalNoThings = colns
.stream()
.collect(
Collectors.groupingBy(
Something::getParentKey,
Collectors.summingInt(ClientCollectionsReceived::getNoThings)));
我认为也许可以包装我的 Something class 并且每个父密钥的总数可能会以某种方式起作用。
class SomethingWrapper {
private int totalNoThingsPerClient;
private Something something;
}
但是看起来工作量很大,不太优雅。
如有任何意见/想法,我们将不胜感激。
好吧,你已经通过收集汇总信息完成了主要工作
Map<Integer, Integer> totalNoThings = somethings.stream()
.collect(Collectors.groupingBy(Something::getParentKey,
Collectors.summingInt(Something::getNoThings)));
那么您需要做的就是在排序操作中利用这些信息:
List<Something> sorted=somethings.stream().sorted(
Comparator.comparing((Something x)->totalNoThings.get(x.getParentKey()))
.thenComparing(Something::getNoThings).reversed())
.collect(Collectors.toList());
实际上不得不做一个小调整,而不是 totalNoThings.get,而是 totalNothings.indexOf
最后的解决方案。是
List<Integer> totalNoThings
= somethings.stream()
.collect(Collectors.groupingBy(Something::getParentKey,
Collectors.summingInt(Something::getNoThings)))
.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.collect(Collectors.toList());
List<Something> sorted
= somethings.stream().sorted(
Comparator.comparing(
(Something obj)->totalNoThings.indexOf(
obj.getParentKey()))
.thenComparing(Something::getNoThings).reversed())
.collect(Collectors.toList());