public class FollowCarAnalysis { private List followCarList;//过车记录集合

//构造方法,接收过车记录集合
public FollowCarAnalysis(List<AnalysisJudgmentFollowCarVO> followCarList) {
    this.followCarList = followCarList;
}

//按照hpzl+hphm分组,并处理符合条件的伴随车辆
public List<FollowCarVO> analysisFollowCar(int X, int Y) {
    List<FollowCarVO> followCarVOList = new ArrayList<>();//新集合

    //1.根据过车记录,将数据按照hpzl+hphm进行分组,用lamda表达式处理
    Map<String, List<AnalysisJudgmentFollowCarVO>> followCarMap = followCarList.stream()
            .collect(Collectors.groupingBy(f -> f.getHpzl() + f.getHphm()));

    //2.对分组后的过车记录进行计算
    for (Map.Entry<String, List<AnalysisJudgmentFollowCarVO>> entry : followCarMap.entrySet()) {
        List<AnalysisJudgmentFollowCarVO> carList = entry.getValue();//同一组的车辆

        for (int i = 0; i < carList.size(); i++) {
            AnalysisJudgmentFollowCarVO car1 = carList.get(i);//第一辆车

            for (int j = i + 1; j < carList.size(); j++) {
                AnalysisJudgmentFollowCarVO car2 = carList.get(j);//第二辆车

                //判断是否为连续经过相同设备的伴随车辆
                if (isFollowCar(car1, car2, X, Y)) {
                    //如果是,将伴随车辆保存到新对象中
                    FollowCarVO followCarVO = new FollowCarVO();
                    followCarVO.setHpzl(car1.getHpzl());
                    followCarVO.setHphm(car1.getHphm());
                    followCarVO.setBscHpzl(car2.getHpzl());
                    followCarVO.setBscHphm(car2.getHphm());
                    followCarVO.setBssj(getBssj(car1, car2));
                    followCarVO.setSbidList(getSbidList(car1, car2));

                    followCarVOList.add(followCarVO);//将新对象添加到新集合中
                }
            }
        }
    }
    return followCarVOList;
}

//判断是否为伴随车辆
private boolean isFollowCar(AnalysisJudgmentFollowCarVO car1, AnalysisJudgmentFollowCarVO car2, int X, int Y) {
    int bscs = 0;//统计连续通过相同设备的次数
    String lastSbid = null;//上一个经过的设备id

    for (AnalysisJudgmentFollowCarVO car : Arrays.asList(car1, car2)) {
        String sbid = car.getSbid();//当前经过的设备id
        String gcsj = car.getGcsj();//当前经过设备的时间

        if (lastSbid != null && lastSbid.equals(sbid)) {//如果当前经过的设备与上一个经过的设备相同
            if (DateUtil.getIntervalMin(gcsj, lastGcsj) <= X) {//且两次经过设备的时间间隔小于X分钟
                bscs++;//连续通过相同设备的次数+1
                if (bscs >= Y) {//如果连续通过相同设备的次数>=Y
                    return true;//判断为伴随车辆
                }
            } else {
                bscs = 0;//如果两次经过设备的时间间隔大于X分钟,连续通过相同设备的次数清零
            }
        } else {//如果当前经过的设备与上一个经过的设备不同,连续通过相同设备的次数清零
            bscs = 0;
        }
        lastSbid = sbid;//保存上一个经过的设备id
        lastGcsj = gcsj;//保存上一个经过设备的时间
    }
    return false;
}

//计算伴随时间,返回字符串类型的分钟数
private String getBssj(AnalysisJudgmentFollowCarVO car1, AnalysisJudgmentFollowCarVO car2) {
    String firstGcsj = null;//第一辆车经过第一个相同设备的时间
    String lastGcsj = null;//第二辆车经过最后一个相同设备的时间

    for (AnalysisJudgmentFollowCarVO car : Arrays.asList(car1, car2)) {
        if (firstGcsj == null || DateUtil.compareDate(car.getGcsj(), firstGcsj) < 0) {
            firstGcsj = car.getGcsj();//保存第一辆车经过第一个相同设备的时间
        }
        if (lastGcsj == null || DateUtil.compareDate(car.getGcsj(), lastGcsj) > 0) {
            lastGcsj = car.getGcsj();//保存第二辆车经过最后一个相同设备的时间
        }
    }
    return String.valueOf(DateUtil.getIntervalMin(firstGcsj, lastGcsj));//计算伴随时间,返回字符串类型的分钟数
}

//获取连续通过的相同设备(sbid)集合
private List<String> getSbidList(AnalysisJudgmentFollowCarVO car1, AnalysisJudgmentFollowCarVO car2) {
    List<String> sbidList = new ArrayList<>();//设备id集合
    String lastSbid = null;//上一个经过的设备id

    for (AnalysisJudgmentFollowCarVO car : Arrays.asList(car1, car2)) {
        String sbid = car.getSbid();//当前经过的设备id

        if (lastSbid != null && lastSbid.equals(sbid)) {//如果当前经过的设备与上一个经过的设备相同
            sbidList.add(sbid);//将设备id添加到集合中
        }
        lastSbid = sbid;//保存上一个经过的设备id
    }
    return sbidList;
}

原文地址: https://www.cveoy.top/t/topic/e1TN 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录