输出解题思路及代码实现到一个类中并将代码按功能点进行拆分 每步代码上方要有注释。现已根据统计条件中的开始结束日期查出过车记录集合ListAnalysisJudgmentVehiceFollowVO并已按照gcsj升序排序AnalysisJudgmentVehiceFollowVO属性有sbidsbmchpzlhphmgcsj均为String类型。根据过车记录查询每一辆车的可能伴随车辆。规则如下例A
/**
-
根据过车记录查询每一辆车的可能伴随车辆 */ public class AnalysisJudgmentFollowCar {
/**
- 根据过车记录集合查询可能的伴随车辆
- @param records 过车记录集合
- @param interval 时间间隔X,单位:分钟
- @param count 最小伴随次数Y
- @return 伴随车辆集合
*/
public List
findFollowCars(List records, int interval, int count) { // 新集合,保存伴随车辆 List followCars = new ArrayList<>(); // 遍历每一辆车的过车记录 for (int i = 0; i < records.size() - 1; i++) { AnalysisJudgmentVehiceFollowVO recordA = records.get(i); // A车经过的卡口集合 List sbidsA = new ArrayList<>(); sbidsA.add(recordA.getSbid()); // 记录A车经过每个卡口的时间 Map<String, String> gcsjMapA = new HashMap<>(); gcsjMapA.put(recordA.getSbid(), recordA.getGcsj()); // 遍历A车之后的每一辆车 for (int j = i + 1; j < records.size(); j++) { AnalysisJudgmentVehiceFollowVO recordB = records.get(j); // B车经过的卡口集合 List sbidsB = new ArrayList<>(); sbidsB.add(recordB.getSbid()); // 记录B车经过每个卡口的时间 Map<String, String> gcsjMapB = new HashMap<>(); gcsjMapB.put(recordB.getSbid(), recordB.getGcsj()); // 比较A车与B车经过的卡口集合,找到相同的卡口 boolean isSameSbids = false; for (String sbidA : sbidsA) { if (sbidsB.contains(sbidA)) { isSameSbids = true; break; } } // 如果A车与B车经过了相同的卡口 if (isSameSbids) { // 记录A车与B车连续经过的卡口集合 List sameSbids = new ArrayList<>(); // 记录A车与B车连续经过的卡口集合中最后一个卡口的过车时间 String lastGcsj = null; int sameCount = 0; // 统计连续相同卡口的次数 // 遍历A车与B车经过的卡口 for (String sbid : sbidsA) { // 如果B车也经过该卡口 if (sbidsB.contains(sbid)) { // 记录连续经过的卡口集合 sameSbids.add(sbid); // 计算A车与B车经过该卡口的时间间隔 long intervalTime = DateUtil.getMinuteInterval(gcsjMapA.get(sbid), gcsjMapB.get(sbid)); // 如果时间间隔小于等于设定的间隔时间 if (intervalTime <= interval) { sameCount++; // 统计连续相同卡口的次数+1 lastGcsj = gcsjMapB.get(sbid); // 更新最后一个卡口的过车时间 } else { // 如果时间间隔大于设定的间隔时间,重置连续相同卡口的次数 sameCount = 1; lastGcsj = gcsjMapB.get(sbid); } } } // 如果连续相同卡口的次数大于等于设定的次数 if (sameCount >= count) { // 新建伴随车辆对象 AnalysisJudgmentFollowCarVO followCar = new AnalysisJudgmentFollowCarVO(); followCar.setHpzl(recordA.getHpzl()); followCar.setHphm(recordA.getHphm()); followCar.setBscHpzl(recordB.getHpzl()); followCar.setBscHphm(recordB.getHphm()); followCar.setBssj(String.valueOf(DateUtil.getMinuteInterval(gcsjMapA.get(sameSbids.get(0)), lastGcsj))); followCar.setSbids(sameSbids); // 将伴随车辆对象添加到集合中 followCars.add(followCar); } } // 如果A车与B车经过的卡口不同,结束遍历B车的过车记录 else { break; } // 添加B车经过的卡口到集合中 sbidsA.add(recordB.getSbid()); // 记录B车经过每个卡口的时间 gcsjMapA.put(recordB.getSbid(), recordB.getGcsj()); } } return followCars; }
}
/**
-
日期时间工具类 */ public class DateUtil {
/**
- 计算两个时间之间的时间间隔,单位:分钟
- @param startTime 开始时间,格式:yyyy-MM-dd HH:mm:ss
- @param endTime 结束时间,格式:yyyy-MM-dd HH:mm:ss
- @return 时间间隔,单位:分钟 */ public static long getMinuteInterval(String startTime, String endTime) { try { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date startDate = format.parse(startTime); Date endDate = format.parse(endTime); long interval = (endDate.getTime() - startDate.getTime()) / (1000 * 60); return interval; } catch (ParseException e) { e.printStackTrace(); return 0; } }
}
/**
-
伴随车辆对象 */ public class AnalysisJudgmentFollowCarVO {
// 车辆号牌种类 private String hpzl; // 车辆号牌号码 private String hphm; // 伴随车辆号牌种类 private String bscHpzl; // 伴随车辆号牌号码 private String bscHphm; // 伴随时间,单位:分钟 private String bssj; // 连续通过的相同的设备(sbid)集合 private List
sbids; // getter/setter // ...
}
/**
-
过车记录对象 */ public class AnalysisJudgmentVehiceFollowVO {
// 设备编号 private String sbid; // 设备名称 private String sbmc; // 车辆号牌种类 private String hpzl; // 车辆号牌号码 private String hphm; // 过车时间,格式:yyyy-MM-dd HH:mm:ss private String gcsj;
// getter/setter // ...
原文地址: https://www.cveoy.top/t/topic/e2Ub 著作权归作者所有。请勿转载和采集!