使用 Java 8 中的流从嵌套数组中查找具有最大平均值的值

问题描述 投票:0回答:2

我把这个作为一个编码面试问题。我能够获得期望的结果并通过所有测试用例。然而我并没有通过面试。我认为这是因为我采用了命令式风格 - 多个 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 个元素对其进行分组,然后对其求和,然后获取平均值。

java java-8 java-stream
2个回答
2
投票

这是一种方法。

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

请注意,我是通过立即流式传输条目并找到最大平均值来做到这一点的。 它也可以分两个单独的步骤完成。首先计算并保存所有个体的平均值图。 然后流式传输条目并找到最大值。

最后,还可以在流式传输源数组后立即添加一些过滤器来检查空数组、空值等,以避免稍后在管道中抛出异常。


0
投票
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>
,其中键是学生的姓名,值是学生的平均分数。 然后,它在映射中查找具有最大值(平均分数)的条目,并返回关联的键(学生姓名)。

© www.soinside.com 2019 - 2024. All rights reserved.