新闻中心

J*a中计算列表数据中按条件分组的连续失败时长

2025-12-12
浏览次数:
返回列表

Java中计算列表数据中按条件分组的连续失败时长

本教程详细介绍了如何在j*a中处理包含时间序列和状态信息的列表数据,以计算每个实体(如用户)的累积失败时长。通过将数据按实体分组,并利用j*a stream api或第三方seq库进行排序和有状态遍历,精确地统计从“失败”状态开始到下一个“成功”状态结束的持续时间。文章提供了具体的代码示例,并讨论了实现细节及注意事项。

在现代数据处理中,我们经常需要从一系列事件记录中提取有意义的聚合信息。一个常见场景是,给定一个包含实体名称、事件日期和状态(例如“成功”或“失败”)的列表,我们需要计算每个实体在特定条件下的累计时长。本教程将以计算“连续失败时长”为例,详细讲解如何使用J*a的Stream API以及第三方库Seq来高效解决此类问题。

问题描述

假设我们有一组按时间顺序排列的事件记录,每条记录包含一个实体名称(name)、事件发生的年份(date)和事件状态(status,可以是"success"或"fail")。我们需要为每个实体计算其总的“失败时长”。失败时长定义为:从一个“失败”状态开始,到紧随其后的第一个“成功”状态结束的时间跨度。如果在一个失败周期中出现多个连续的失败事件,它们将被视为同一失败周期的延续。

示例数据:

[
   {"name":"john", "date":2015, "status":"success"},
   {"name":"john", "date":2013, "status":"fail"},
   {"name":"chris", "date":2013, "status":"success"},
   {"name":"john", "date":2012, "status":"fail"},
   {"name":"john", "date":2009, "status":"success"},
   {"name":"chris", "date":2007, "status":"fail"},
   {"name":"john", "date":2005, "status":"fail"},
]

根据上述定义,对于john:

立即学习“J*a免费学习笔记(深入)”;

微软爱写作 微软爱写作

微软出品的免费英文写作/辅助/批改/评分工具

微软爱写作 130 查看详情 微软爱写作
  • 2005年失败,下一个成功是2009年,失败时长为 2009 - 2005 = 4 年。
  • 2012年失败,2013年再次失败(视为同一失败周期),下一个成功是2015年,失败时长为 2015 - 2012 = 3 年。
  • john的总失败时长为 4 + 3 = 7 年。

对于chris:

  • 2007年失败,下一个成功是2013年,失败时长为 2013 - 2007 = 6 年。
  • chris的总失败时长为 6 年。

数据模型定义

为了更好地组织和处理数据,我们首先定义一个J*a类来表示每条记录,而不是直接使用HashMap。这提供了更好的类型安全性和代码可读性。

public class Record {
    public String name;
    public Integer date; // 使用Integer表示年份
    public String status;

    public Record(String name, Integer date, String status) {
        this.name = name;
        this.date = date;
        this.status = status;
    }

    @Override
    public String toString() {
        return "Record{" +
               "name='" + name + '\'' +
               ", date=" + date +
               ", status='" + status + '\'' +
               '}';
    }
}

核心计算逻辑

解决此类问题的关键在于对数据进行分组和按时间排序,并在遍历过程中维护一个状态。具体步骤如下:

  1. 按实体名称分组:首先,将所有记录根据其name字段进行分组。这样,我们可以独立地处理每个实体的事件序列。
  2. 组内按日期排序:对于每个实体组,必须将其内部的记录按照date字段升序排序。这是确保计算逻辑正确性的前提,因为失败时长的计算依赖于事件的先后顺序。
  3. 有状态遍历计算
    • 在遍历每个实体排序后的记录时,我们需要维护一个变量来记录当前是否处于一个失败周期中,以及该失败周期的起始日期。我们可以使用一个Integer类型的变量lastFailDate,初始值为null。
    • 当遇到一条状态为"fail"的记录时:
      • 如果lastFailDate为null,表示这是一个新的失败周期的开始,我们将当前记录的date赋值给lastFailDate。
      • 如果lastFailDate不为null,表示失败周期正在持续,我们不需要更新lastFailDate(因为我们只关心失败的起始点)。
    • 当遇到一条状态为"success"的记录时:
      • 如果lastFailDate不为null,表示当前有一个未结束的失败周期。此时,计算当前成功记录的date与lastFailDate之差,作为本次失败的时长,并将其累加到该实体的总失败时长中。
      • 计算完成后,将lastFailDate重置为null,表示该失败周期已经结束。
    • 如果lastFailDate为null,则忽略当前成功记录,因为它没有前置的失败周期。

使用J*a Stream API实现

J*a 8引入的Stream API为集合处理提供了强大而灵活的工具。我们可以利用它来实现上述逻辑。

import j*a.util.List;
import j*a.util.Map;
import j*a.util.Comparator;
import j*a.util.stream.Collectors;

public class FailureDurationCalculator {

    public static Map<String, Integer> calculateFailureDurationWithStream(List<Record> records) {
        return records.stream()
            // 1. 按名称分组:将所有记录根据其name字段分组,得到Map<String, List<Record>>
            .collect(Collectors.groupingBy(r -> r.name))
            .entrySet().stream() // 将Map的entrySet转换为Stream,以便进一步处理每个分组
            // 2. 对每个分组计算失败时长,并收集到最终的Map<String, Integer>中
            .collect(Collectors.toMap(Map.Entry::getKey, entry -> {
                // 使用数组作为可变变量,以在Lambda表达式中存储上一次失败的日期。
                // Stream操作通常是无状态的,但这里需要维护一个跨记录的状态。
                Integer[] lastFailDate = new Integer[]{null};

                return entry.getValue().stream()
                    // 3. 对每个分组内的记录按日期升序排序
                    .sorted(Comparator.comparing(r -> r.date))
                    .mapToInt(record -> {
                        if ("fail".equals(record.status) && lastFailDate[0] == null) {
                            // 遇到失败,且当前没有正在进行的失败期,记录失败开始日期
                            lastFailDate[0] = record.date;
                        } else if ("success".equals(record.status) && lastFailDate[0] != null) {
                            // 遇到成功,且有正在进行的失败期,计算时长
                            int duration = record.date - lastFailDate[0];
                            lastFailDate[0] = null; // 重置失败开始日期,表示该失败周期已结束
                            return duration;
                        }
                        return 0; // 其他情况(如连续失败、成功后无失败等)不产生时长
                    })
                    .sum(); // 累加所有计算出的失败时长,得到该实体的总失败时长
            }));
    }

    public static void main(String[] args) {
        List<Record> records = List.of(
            new Record("john", 2015, "success"),
            new Record("john", 2013, "fail"),
            new Record("chris", 2013, "success"),
            new Record("john", 2012, "fail"),
            new Record("john", 2009, "success"),
            new Record("chris", 2007, "fail"),
            new Record("john", 2005, "fail")
        );

        Map<String, Integer> failureDurations = calculateFailureDurationWithStream(records);
        System.out.println("使用Stream API计算的失败时长: " + failureDurations); // 预期输出: {chris=6, john=7}
    }
}

以上就是J*a中计算列表数据中按条件分组的连续失败时长的详细内容,更多请关注其它相关文章!


# 自定义  # 营销推广的手段包括  # 锦州本地网站优化哪里好  # 岑巩县营销推广报价  # 义乌网站建设招标公示网  # seo高权重怎么排名  # 河南网站建设系统介绍  # seo排名异常  # 百度关键词营销推广公司  # 橡塑网站优化策略  # 陕西seo服务公司  # 错误信息  # 第三方  # 不为  # java  # 此类  # 子类  # 升序  # 遍历  # 微软  # 时长  # red  # java类  # 排列  # 代码可读性  # stream  # ai  # 工具 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: Golang如何使用bytes.Split分割字节切片_Golang bytes切片分割方法  苹果手机如何防止被恶意App追踪  J*a应用程序首次运行自动创建文件与目录的最佳实践  Win11文件资源管理器卡顿怎么修 Win11重置资源管理器进程优化响应速度【修复方法】  126邮箱手机版登录官网2026_126手机邮箱免费入口最新  css滚动动画效果怎么实现_使用Animate.css滚动触发动画类  支付宝如何管理隐私设置_支付宝隐私保护的配置技巧  PyTorch模型训练效果不佳?深入剖析常见错误与调试技巧  如何将HTML表格多行数据保存到Google Sheet  C++如何实现异步操作_C++11使用std::future和std::async进行异步编程  qq邮箱发邮件给国外发不出去_QQ邮箱国际邮件发送失败原因与解决  J*aScript中高效管理与清空动态列表:避免循环陷阱  聚水潭ERP登录页面入口 聚水潭ERP官网登录界面  mysql通配符支持数字匹配吗_mysql通配符能否用于数字匹配的解析  LINUX的perf命令入门_LINUX官方性能分析工具的使用与解读  Win10快速启动功能利弊分析 Win10开启或关闭快速启动教程【技巧】  利用Bokeh CustomJS动态控制DataTable列可见性  PPT平滑切换怎么做 PPT炫酷“平滑”切换动画制作教程【必学】  神经网络二分类模型训练异常:高损失与完美验证准确率的排查与修正  Win11 BitLocker密码忘了怎么办 Win11找回BitLocker恢复密钥方法【解决】  不同用户不同价格! 索尼开启账户个性化定价测试  J*a 递归快速排序中静态变量的状态管理与陷阱  AI抖音网页版免费视频入口 AI抖音网页端最新视频实时观看  小米14应用无法联网原因分析_小米14网络权限修复  如何在 Excel Online 和 Google 表格中更改日期格式  qq浏览器打开空白页怎么办 qq浏览器启动后显示白屏的解决教程  KFC套餐升级怎么获取优惠代码_KFC套餐升级活动与优惠代码获取方法  Win10如何开启蓝牙功能_Windows10找不到蓝牙开关解决方法  使用 Pandas 高效处理 .dat 文件:数据清洗与数值计算实战  优化 Python 函数中的条件逻辑:解决 if-else 嵌套与参数选择问题  Python:递归比较文件夹内容并找出特定类型文件的差异  Sublime怎么配置Nim语言环境_Sublime Nim代码高亮与补全  Sublime Text怎么显示空格和制表符_Sublime显示不可见字符设置  c++20的std::jthread是什么_c++可中断线程与RAII式管理  Mac怎么锁定备忘录_Mac备忘录加密设置教程  冬*霸灯泡不亮怎么办_浴霸取暖灯一盏不亮的灯座清洁修复法  Python模块化编程:有效管理依赖与避免循环引用  css子元素高度不一致导致布局错位怎么办_使用align-items:stretch解决高度差异  Yandex官网搜索引擎免登录_俄罗斯Yandex一键直达入口  想当下一个《2077》?《心之眼》Steam评价升至"多半好评"  深入理解J*aScript Promise异步执行与微任务队列  曝R星经典之作开发图 设计简陋但信息密集!  正确连接J*aScript到HTML实现可点击图片与自定义事件处理  手机屏幕碎了但能正常使用怎么办 手机外屏碎裂的修复建议  b站如何看历史记录_b站观看历史找回方法  高德地图总提示网络异常怎么办 高德地图离线导航设置与网络排查方法  J*aScript中安全有效地处理localStorage字符串数据  2025AO3夸克浏览器通道_AO3手机HTTPS安全入口分享  Google翻译怎么语音输入_Google翻译语音输入功能使用与设置方法  ArchiveofOurOwn小说阅读-ArchiveofOurOwn同人作品访问链接 

搜索