我把这个作为一个编码面试问题。我能够获得期望的结果并通过所有测试用例。然而我并没有通过面试。我认为这是因为我采用了命令式风格 - 多个 for 循环、多个
HashMap
等。我试图使用流来实现相同的结果。问题来了:
给定一个数组
String[][]
例如:{{"Scott","85"},{"Scott","67"},{"Tiger","81"},{"Tiger","21"},{"Marissa","92"}}
,找到平均分最高的人。下面是我所能得到的代码片段。
public static void main(String[] args) {
String[][] scores = {{"Tee","63"},{"Tee","75"},{"Tee","84"},{"Dee","59"},{"Dee","77"},{"Dee","66"},{"Dee","71"},{"Lee","81"},{"Lee","78"},{"Lee","58"},{"Bree","98"},{"Bree","78"}};
List<List<String>> slist = Arrays.stream(scores)
.map(Arrays::asList)
.collect(Collectors.toList());
slist.stream().collect(Collectors.groupingBy(l->l.get(0)));
}
我能够将
String[][]
转换为 List<List<String>>
。我希望流式传输这个新列表,按第 0 个元素对其进行分组,然后对其求和,然后获取平均值。
这是一种方法。
String[][] scores = {{"Tee","63"},{"Tee","75"},{"Tee","84"},{"Dee","59"},
{"Dee","77"},{"Dee","66"},{"Dee","71"},{"Lee","81"},{"Lee","78"},{"Lee","58"},
{"Bree","98"},{"Bree","78"}};
Map<String, Double>
以获取姓名和平均值。Collectors.groupingBy
并使用 Collectors.averagingDouble
计算每个值的平均值来找到平均值。 最后一个收集器被 ToDoubleFunction
告知要平均哪个值,在这种情况下,它必须对流中每个数组的第二个值进行双精度或整数解析。maxBy
收集器比较
Entry values
为最高。maxBy
返回一个可选值,因此首先检查值是否存在(源数组可能为空),然后使用 get
来检索它。Optional<Entry<String, Double>> max = Arrays.stream(scores)
.collect(Collectors.groupingBy(a->a[0],
Collectors.averagingDouble(a->Double.parseDouble(a[1]))))
.entrySet()
.stream()
.collect(Collectors.maxBy(Entry.comparingByValue()));
if (max.isPresent()) {
Entry<String,Double> result = max.get();
System.out.printf("%s has the highest average of %.2f%n",
result.getKey(),result.getValue());
} else {
System.out.println("No maximum found");
}
打印
Bree has the highest average of 88.00
请注意,我是通过立即流式传输条目并找到最大平均值来做到这一点的。 它也可以分两个单独的步骤完成。首先计算并保存所有个体的平均值图。 然后流式传输条目并找到最大值。
最后,还可以在流式传输源数组后立即添加一些过滤器来检查空数组、空值等,以避免稍后在管道中抛出异常。
String person = Arrays.stream(scores)
.collect(Collectors.groupingBy(
s -> s[0],
Collectors.averagingInt(s -> Integer.parseInt(s[1]))))
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElseThrow();
首先将数组分组为
Map<String, Double>
,其中键是学生的姓名,值是学生的平均分数。 然后,它在映射中查找具有最大值(平均分数)的条目,并返回关联的键(学生姓名)。