我有List<MyObjects>
,其中包含4个字段:
String fieldText;
double fieldDoubleOne;
double fieldDoubleTwo;
double fieldDoubleThree;
最好的(Java-8)方式是收集和打印列表,并根据Average(fieldDoubleOne)进行排序,以便控制台输出类似于: fieldText→平均值(fieldDoubleTwo)→平均值(fieldDoubleTwo)→平均值(fieldDoubleThree) 假定所有领域的公众获取者。对于一个双字段,我有from my previous question:
Map<String, List<MyObject>> groupByFieldText = myObjectList.stream().collect(groupingBy(MyObject::getFieldText));
Map<String, Double> averageMap = groupByFieldText.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey(),
e.getValue().stream()
.mapToDouble(d -> d.getDoubleOne()).average()
.orElse(0d)))
.sorted(Comparator.comparingDouble(Map.Entry::getValue))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(v1, v2) -> v1, LinkedHashMap::new));
averageMap.entrySet().stream().sorted(Comparator.comparingDouble((Map.Entry::getValue)))
.forEach(System.out::println);
答案 0 :(得分:0)
您只需要对条目进行排序,而不是像这样将其值映射到double
:
Map<String, List<MyObject>> sortedByAverageOne = groupByFieldText.entrySet().stream()
.sorted(Comparator.comparingDouble(e -> average(e, MyObject::getDoubleOne)))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(v1, v2) -> v1, LinkedHashMap::new));
请注意,如果您有很多条目,则效率不高,因为它会调用average
进行每次比较。
然后,在具有排序后的地图的情况下,按以下方式打印它:
sortedByAverageOne.entrySet().stream()
.map(e -> String.format(
"%s → %f → %f → %f",
e.getKey(),
average(e, MyObject::getDoubleOne),
average(e, MyObject::getDoubleTwo),
average(e, MyObject::getDoubleThree)
))
.forEach(System.out::println);
最后,average
定义为:
private static double average(Map.Entry<String, List<MyObject>> entry, ToDoubleFunction<MyObject> getter) {
return average(entry.getValue(), getter);
}
private static double average(List<MyObject> list, ToDoubleFunction<MyObject> getter) {
return list.stream().mapToDouble(getter).average().orElse(0);
}