Java Stream API:高效处理和排序学生成绩数据

Java Stream API:高效处理和排序学生成绩数据

本文深入探讨如何利用Java Stream API高效处理学生成绩数据。我们将学习如何收集、计算学生平均分,并在此基础上进行过滤和降序排序,最终以指定格式输出结果。文章强调通过预计算平均分来优化性能,并利用Stream API的强大功能简化代码逻辑。

1. 数据收集与初始存储

在处理学生成绩数据时,通常需要将每个学生的多个成绩关联起来。一个常见的做法是使用 map<string, list> 来存储,其中键是学生姓名(string),值是该学生所有成绩的列表(list<double)。

以下代码片段展示了如何从标准输入读取学生姓名和成绩,并将其存储到 Map 中:

import java.util.*;import java.util.stream.Collectors;public class Main {    public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        int n = Integer.parseInt(scanner.nextLine()); // 读取学生-成绩对的数量        Map<String, List> records = new HashMap();        // 循环读取数据并存储        while(n > 0){            String name = scanner.nextLine();            double grade = Double.parseDouble(scanner.nextLine());            // 如果学生不存在,则添加新列表;否则,将成绩添加到现有列表            records.putIfAbsent(name, new ArrayList());            records.get(name).add(grade);            n--;        }        // ... 后续处理    }}

2. Stream API处理的挑战与优化思路

在处理完原始数据后,我们需要执行以下操作:

计算每个学生的平均分。过滤掉平均分低于特定阈值(例如 4.50)的学生。根据平均分进行降序排序。以指定格式打印结果。

最初的实现可能会在 filter 和 sorted 操作中多次计算平均分,这会导致性能下降。例如,在 sorted 操作的 Comparator 中再次计算平均分,不仅冗余,而且将 double 类型的差值强制转换为 int ((int) (average2 – average1)) 可能导致排序不准确,因为小数部分的差异会被截断。

为了解决这个问题,最佳实践是预先计算并存储平均分。我们可以将原始的 Map<String, List> 转换为 Map,其中键是学生姓名,值是其对应的平均分。

立即学习“Java免费学习笔记(深入)”;

3. 预计算学生平均分

使用 Java Stream API 的 Collectors.toMap 可以优雅地完成这一转换:

// 将原始记录转换为包含平均分的MapMap recordsWithAverage = records.entrySet()    .stream()    .collect(Collectors.toMap(        Map.Entry::getKey, // 使用原始Map的键作为新Map的键(学生姓名)        e -> e.getValue().stream().mapToDouble(x -> x).average().orElse(0.0) // 计算平均分,如果列表为空则默认为0.0    ));

注意事项: average() 方法返回一个 OptionalDouble。为了避免在学生没有成绩时调用 getAsDouble() 抛出 NoSuchElementException,我们使用 orElse(0.0) 提供一个默认值(例如 0.0),尽管在本场景中,根据问题描述,每个学生都会有成绩。

Imagine By Magic Studio Imagine By Magic Studio

AI图片生成器,用文字制作图片

Imagine By Magic Studio 79 查看详情 Imagine By Magic Studio

4. 过滤、排序与输出

有了包含平均分的 recordsWithAverage 之后,后续的过滤和排序操作将变得更加高效和简洁。

// 对包含平均分的Map进行过滤、排序和输出recordsWithAverage.entrySet()    .stream()    .filter(e -> e.getValue() >= 4.50) // 过滤平均分大于或等于4.50的学生    .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) // 按平均分降序排序    .forEach(pair -> {        // 格式化输出:姓名 -> 平均分 (保留两位小数)        System.out.printf("%s -> %.2f%n", pair.getKey(), pair.getValue());    });

代码解析:

filter(e -> e.getValue() >= 4.50):直接使用 Map.Entry 的值(即平均分)进行过滤。sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())):这是排序的关键。Map.Entry.comparingByValue():这是一个方便的 Comparator 工厂方法,它会创建一个 Comparator,用于比较 Map.Entry 对象的。Comparator.reverseOrder():用于将默认的升序排序转换为降序排序。通过组合这两个方法,我们实现了按平均分降序排序,无需手动编写复杂的 lambda 表达式。forEach(pair -> System.out.printf(“%s -> %.2f%n”, pair.getKey(), pair.getValue())):遍历排序后的结果,并使用 printf 方法以指定格式输出,其中 %.2f 用于将 double 值格式化为保留两位小数的浮点数。

5. 完整代码示例

结合以上所有步骤,完整的解决方案如下:

import java.util.*;import java.util.stream.Collectors;public class Main {    public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        int n = Integer.parseInt(scanner.nextLine());        // 1. 数据收集与初始存储        Map<String, List> records = new HashMap();        while(n > 0){            String name = scanner.nextLine();            double grade = Double.parseDouble(scanner.nextLine());            records.putIfAbsent(name, new ArrayList());            records.get(name).add(grade);            n--;        }        // 2. 预计算学生平均分        Map recordsWithAverage = records.entrySet()            .stream()            .collect(Collectors.toMap(                Map.Entry::getKey,                e -> e.getValue().stream().mapToDouble(x -> x).average().orElse(0.0) // 处理空列表情况            ));        // 3. 过滤、排序与输出        recordsWithAverage.entrySet()            .stream()            .filter(e -> e.getValue() >= 4.50) // 过滤平均分            .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) // 按平均分降序排序            .forEach(pair -> {                System.out.printf("%s -> %.2f%n", pair.getKey(), pair.getValue()); // 格式化输出            });        scanner.close(); // 关闭Scanner    }}

总结

通过本教程,我们学习了如何使用 Java Stream API 高效地处理和排序复杂数据结构。核心优化点在于:

避免重复计算: 在进行过滤和排序之前,预先计算并存储派生值(如平均分),可以显著提高性能。善用 Collectors: Collectors.toMap 等方法提供了强大的数据转换能力,能够将一种集合类型高效地转换为另一种。利用 Comparator 工具方法: Map.Entry.comparingByValue() 和 Comparator.reverseOrder() 等 Comparator 工厂方法使排序逻辑更加简洁和易读,同时避免了 double 到 int 强制类型转换可能导致的精度问题。

掌握这些技巧,将有助于您编写更高效、更具可读性的 Java Stream API 代码。

以上就是Java Stream API:高效处理和排序学生成绩数据的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/773955.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月26日 06:39:31
下一篇 2025年11月26日 06:39:53

相关推荐

  • 甘特图选择困难症?过来人推荐哪款好用?

    最佳甘特图推荐:实践经验分享 在甘特图选择上苦苦寻求?以下是我们的推荐,专为那些亲身体验过的用户准备。 问题: 有推荐的甘特图推荐吗?最好是有实践经验的。市面上有不少选择,Ext JS 的官方网站却没有提及。是否有 Ext JS 的甘特图推荐? 回答: 经过深入搜索和实际使用,我们推荐以下甘特图: …

    2025年12月9日
    000
  • 有哪些好用的甘特图工具推荐?

    使用过的好用甘特图工具 对于甘特图工具,推荐使用 https://github.com/taitems/jQuery.Gantt/,因为它操作便捷且功能强大,许多程序员都对该工具给予了肯定的评价。 尽管 ExtJS 官网上可能没有专门的甘特图组件,但您可以使用第三方库或插件来实现甘特图功能。例如,j…

    2025年12月9日
    000
  • PHP中如何将XML文件处理结果存入变量?

    将处理xml文件的结果存入变量中 php中,你可以利用simplexml_load_string()函数将xml字符串转换为simplexml对象,该对象可以方便地访问xml文档中的数据。以下是一个示例,展示如何将xml文件的结果存入变量中: $string = <<<XML st…

    2025年12月9日
    000
  • PHP如何读取和处理XML文件并将数据保存到变量中?

    php 读取和处理 xml 文件 为了将 xml 文件中的数据保存到变量中,我们需要利用 php 中的内置函数。这通常涉及以下步骤: 加载 xml 文件: $xmlstring = ‘ status message remainpoint taskid successcounts’;$xmlobje…

    2025年12月9日
    000
  • PHP如何将XML文件内容解析并存储到变量中?

    php处理xml文件,将结果存入变量中 通过php对xml文件进行处理,可以将xml节点中的值提取出来,并存储到php变量中,以便于后期使用。具体步骤如下: 使用simplexml_load_string()函数加载xml字符串:可以使用该函数将xml字符串转换为simplexml对象,方便后续操作…

    2025年12月9日
    000
  • 如何将多层嵌套的JSON对象转换为易于操作的多维数组?

    给的json数据中,有很多层的对象,将对象嵌套多层不直观,所以一般我们将其转换为多维数组进行操作,转换方法便是遍历对象,然后将对象的每个属性挂载到该层级上,如果对象的属性具有子属性,则继续进行嵌套操作.具体操作: ‘use strict’;function convert(obj,keys,arr)…

    2025年12月9日
    000
  • Ubuntu下PHP无法创建目录或写入文件:如何解决权限问题?

    ubuntu 下 php 无法创建目录和写入文件 在 ubuntu 中配置 lamp 环境时,用户可能会遇到 php 无法创建目录及写入文件的情况。即使已将项目权限设置为 777,apache 仍会报告错误。本文将针对此问题提供解决方案。 php 代码片段如下: $max_size = 10000;…

    2025年12月9日
    000
  • 如何实现PHP AES RSA加密算法与C#和Java的互通?

    php aes rsa 算法修改以与 c# 和 java 互通 您希望将 php 中的 aes 和 rsa 加密算法修改为与 c# 和 java 互通。具体来说,您希望能够使用这些语言相互加密和解密数据。 一种实现此目标的途径是创建一个 php 加密服务。该服务将作为一个中间层,允许您使用 c# 和…

    2025年12月9日
    000
  • 如何用jQuery实现类似谷歌搜索的自动提示功能?

    实现类似google suggest的功能 问题: 如何实现类似谷歌搜索框的自动提示功能? 回答: 可以使用 [jquery ui 自动提示](http://jqueryui.com/autocomplete/) 来实现此功能。 该插件为 控件提供自动完成功能。它从预定义的选项列表中提取匹配建议,并…

    2025年12月9日
    000
  • 如何解决系统参数设置中出现的“hash_file: failed to open stream”错误?

    根据企业情况设置系统参数 在设置系统参数时,如果遇到“hash_file(up/1437616281如何根据企业情况设置系统参数?.doc): failed to open stream: Invalid argument”错误时,可以通过以下方法解决: 当输入的路径是中文路径时,系统不会报错。但是…

    2025年12月9日
    000
  • 如何从数据库中获取数据并以 PHP 形式形成?

    要从 PHP 数据库中获取数据并将其显示在表单中,通常需要执行以下步骤:1.连接到数据库:使用 MySQLi 或 PDO 建立到数据库的连接。2.查询数据库:执行SQL查询以检索所需的数据。3.获取数据:从查询结果中获取数据。4.填充表单:使用获取的数据填写表单字段。 这是一个使用的简单示例MySQ…

    2025年12月9日
    000
  • 创建专注的领域应用程序 Symfony 方法(返回结果)

    介绍 这是本系列的最后一篇文章。在上一篇文章中,我们创建了一个应用程序服务,它使用 userentitybuilder 服务来创建实体。然后,使用条令实体管理器(这是一个基础设施服务)来持久化和刷新实体。 现在,是时候将结果返回到表示层了。 我想记住,在本系列的所有文章中,我们都将学说实体视为域实体…

    2025年12月9日
    000
  • (我的第一次)安装 Laravel

    有时,尤其是当您刚刚开始职业生涯时,您似乎遵循了指示却一事无成 – 而其他人似乎发现这非常容易。 这可能非常令人沮丧,我想描述一下即使在几十年之后我也经历完全相同的事情的几种方式。所以我在这里,试图详细描述我在努力让事情顺利进行时所犯的错误和失误。这是我关于这个主题的第一篇文章,但我希望…

    2025年12月9日
    000
  • PHP 与 MySQL:终极分步指南

    php 是一种语言,可让您在开发网页时灵活地连接和使用不同的数据库。有不同的数据库,既有商业的,也有免费使用的。其中,mysql 是与 php 并列最常用的数据库。 MySQL 是一个开源、免费使用的关系型数据库管理 系统(关系数据库管理系统)。它是一个快速、简单且高度可扩展的程序 因此可用于小型和…

    2025年12月9日 好文分享
    000
  • 您需要的 PHP CRUD 操作的最佳指南

    crud 操作通常在数据库上执行,因此,在本 php crud 操作教程中,您将借助 php 在 mysql 数据库上实现 crud 技术。    crud 缩写包含在关系数据库上执行的所有主要操作。它代表: c = 创建 r = 读取 u = 更新 d = 删除 你现在就会明白不同操作的详细信息。…

    2025年12月9日 好文分享
    000
  • 我最终尝试了 Pest for PHP & Laravel,然后进行了切换

    我在2015年中开始学习纯php。然后,我熟悉了codeigniter 3和laravel 5.1。多年来,laravel 是我选择的框架,而且我仍然坚持使用它。与其他流行的 php 项目一样,我认为 phpunit 是单元测试的唯一选择。但2021年佩斯来了,情况发生了一点变化。它是由 larav…

    2025年12月9日
    000
  • 如何修复 Windows 上的 PHP Curl HTTPS 证书颁发机构问题

    成功的 HTTPS 请求涉及 HTTP 客户端验证 服务器根据已知且受信任的根列表提供的 TLS 证书 证书。 PHP Curl 扩展没有什么不同;卷曲 扩展使用 libcurl 发出 HTTPS 请求,而 libcurl 又使用 OpenSSL 等 TLS 库来验证请求。 Curl 扩展需要一个包…

    2025年12月9日
    000
  • 如何从 PHP 文本输入中查找字符串

    我们可以使用两种不同的方法以编程方式从大型文本输入字符串中定位和检索内容。 我们可以 1) 逐字搜索文本输入(相当于在文档或浏览器中使用“CTRL F”搜索),或者我们可以 2) 通过正则表达式搜索文本表达式。 使用 下面提供的代码示例,我们可以轻松利用两个 分别执行两种搜索方法的免费 API。我们…

    2025年12月9日
    000
  • 在 Laravel 应用程序中集成第三方 API 的分步指南

    主题:laravel、api、thirdpartyintegration、web 开发 php laraveltips apisinlaravel 将第三方 api 集成到 laravel 中可以通过利用外部服务(例如支付、数据检索等)来增强您的应用程序。以下是有效集成第三方 api 的分步指南和示…

    2025年12月9日
    000
  • 要避免的 fetch() 和 XMLHttp 错误

    可悲的是,我没有避免这些错误。我希望这可以帮助其他人在尝试更新网页而不完全下载新版本时避免它们。我最终得到的代码似乎有效: async function fetchdbsingle(url, str) { const datatosend = str; console.log(‘fetchdbsin…

    2025年12月9日
    000

发表回复

登录后才能评论
关注微信