我正在尝试从下面的二维数组中找到最佳的平均分数:
String[][] scores = { { "Amit", "70" }, { "Arthit", "60" }, { "Peter", "60" }, { "Arthit", "100" } };
输出为: 80(Arthit得分(60 + 100)/ 2)
到目前为止,我已经通过以下方法解决了这个问题,但是我正在寻找流的优雅解决方案:
public static void main(String[] args) {
String[][] scores = { { "Amit", "70" }, { "Arthit", "60" }, { "Peter", "60" }, { "Arthit", "100" } };
int highestAvg = Integer.MIN_VALUE;
Function<String[], Integer> function = new Function<String[], Integer>() {
@Override
public Integer apply(String[] t) {
int sum = 0, count = 0;
for (int i = 0; i < scores.length; i++) {
if (t[0].equals(scores[i][0])) {
count++;
sum += Integer.parseInt(scores[i][1]);
}
}
int avg = sum / count;
return highestAvg < avg ? avg : highestAvg;
}
};
System.out.println(Arrays.stream(scores).map(function).max((o1, o2) -> o1.compareTo(o2)).get());
}
请您提出建议,使用流处理二维数组的更好方法是什么?
注意:我不是在寻找确切的解决方案,只是在寻找您的宝贵建议。
答案 0 :(得分:9)
您可以更多地使用内置的流功能,包括averaging和grouping收集器:
Stream.of(scores)
.collect(
Collectors.groupingBy(a -> a[0],
Collectors.averagingInt(a -> Integer.parseInt(a[1]))))
.entrySet()
.stream()
.max(Entry.comparingByValue())
.ifPresent(bestScore -> {
String message = String.format("Best score is %s, by %s", bestScore.getValue(), bestScore.getKey());
System.out.println(message);
});
哪个打印Best score is 80.0, by Arthit
答案 1 :(得分:2)
我知道答案已经提交并已经接受,但是只是分享我在尝试回答您的问题时发现的内容。
Map<String, Double> collect = Arrays.stream(scores)
.collect(Collectors.groupingBy(arr -> arr[0],
Collectors.averagingDouble(arr -> Integer.parseInt(arr[1]))));
这里key
是他的名字,value
是他的分数的平均值。现在,您可以遍历此地图以找到最大值,从而找到最大键的索引。
编辑:
要从地图中找到最大值,请使用:
Entry<String, Double> entry = collect.entrySet().stream()
.max(Map.Entry.comparingByValue(Comparator.comparingDouble(e -> e.doubleValue())))
.get();
答案 2 :(得分:2)
由于要获得的结果是最高的平均分数,因此您可以执行以下操作:
Collection<Double> values = Arrays.stream(scores)
.collect(groupingBy(a -> a[0], averagingInt(a -> Integer.parseInt(a[1]))))
.values();
System.out.println(Collections.max(values));
这会流过scores
多维数组,并使用groupingBy
收集器按元素名称将元素累加成组,然后使用averagingInt
作为下游收集器来获取平均值和然后最后使用Collections.max(values)
来获得最佳的平均分数。
另一种方法:
double bestAverage =
Arrays.stream(scores)
.collect(groupingBy(a -> a[0], averagingInt(a -> Integer.parseInt(a[1]))))
.values()
.stream()
.mapToDouble(Double::doubleValue)
.max().getAsDouble();
System.out.println(bestAverage);
请注意,如果源为空,则上述两种方法都会导致异常,因此,如果要处理该异常,则可以使用isPresent
或其他一些Optional方法,例如orElse
等。
Arrays.stream(scores)
.collect(groupingBy(a -> a[0], averagingInt(a -> Integer.parseInt(a[1]))))
.values()
.stream()
.mapToDouble(Double::doubleValue)
.max().ifPresent(v -> ...);
进口:
import java.util.stream.*;
import static java.util.stream.Collectors.*;