核心是解耦工位位置与打卡时刻:输入流用bufferedreader逐行解析csv数据,按逗号拆分并校验;工位编号映射为point坐标,通过distanceto方法用勾股定理计算物理距离;配对逻辑依需求选择按工号分组排序或任意两行组合;预处理拦截坐标缺失、时间异常等边界情况。

用输入流读取多工位打卡时间并计算两个节点的物理差值,核心是把“工位位置”和“打卡时刻”解耦处理:输入流负责按行解析原始数据(如 CSV 或空格分隔文本),类负责封装坐标建模与距离计算逻辑,不混入 I/O 或业务规则。
输入流读取打卡数据
假设每行格式为:工号,工位编号,时间戳(毫秒),例如:001,W01,1749287250000。推荐使用 BufferedReader 逐行读取,避免一次性加载大文件:
- 用
String.split(",")拆分字段,注意校验数组长度和数字格式 - 时间戳直接转
long,不建议再转Date或LocalDateTime—— 物理差值只关心数值差,不涉及时区或日历 - 工位编号映射为预设坐标,例如
W01 → (10.0, 5.0)、W02 → (15.0, 8.0),可存在Map<string point></string>中
定义工位坐标类
用简单不可变类封装二维位置,便于复用和测试:
- 字段声明为
final double x, y - 提供构造方法和
distanceTo(Point other)方法,内部用勾股定理:Math.sqrt(Math.pow(x - other.x, 2) + Math.pow(y - other.y, 2)) - 不依赖任何日期或时间类,纯粹几何计算
配对计算两个节点差值
“两个节点”指任意两个工位记录(不限于同一人),关键在明确配对逻辑:
- 若需计算某人从 A 工位到 B 工位的移动距离,先按工号分组,再按时间戳排序,取相邻两条记录对应的工位坐标
- 若只需任意两行间的物理距离,读取时缓存
List<record></record>,其中Record含empId、stationId、timestamp、point - 调用
pointA.distanceTo(pointB)即得米(或任意单位)级距离,结果为double
处理常见边界情况
真实产线数据常含噪声,应在计算前拦截:
- 工位编号查不到坐标 → 跳过该行或抛自定义异常(如
UnknownStationException) - 时间戳非数字或负数 → 记录警告日志,不中断流程
- 两点坐标完全相同 → 返回
0.0,无需特殊处理 - 跨工位但时间倒序(如后打的卡时间更早)→ 不影响距离计算,但可额外标记“时间异常”供排查











