多时段合并去重

项目中要去对多时段合并去重
例如:
2020/05/05-2020/05/09的08:00-9:30
2020/05/06-2020/05/12的08:30-12:30
2020/05/10-2020/05/17的11:00-14:00
合并去重完之后:
2020/06/05 08:00-9:30
2020/06/06-2020/06/09 08:00-12:30
2020/06/10-2020/06/12 08:30-14:00
2020/06/13-2020/06/17 11:00-14:00

package com.key.win.vo;

public class MyTime implements Comparable<MyTime> {
    private int start;
    private int end;

    public MyTime(int start, int end) {
        super();
        this.start = start;
        this.end = end;
    }

    public MyTime() {
    }

    public int getStart() {
        return start;
    }

    public int getEnd() {
        return end;
    }

    public int compareTo(MyTime other) {
        if (start == other.start) {
            return other.end - end;
        }
        return start - other.start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public void setEnd(int end) {
        this.end = end;
    }

}

package com.key.win.vo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TimeVo {

    private List<Date>   dates          = new ArrayList<Date>();
    private List<String> dateStrs       = new ArrayList<String>();
    private List<String> specialPeriods = new ArrayList<String>();

    public List<Date> getDates() {
        return dates;
    }

    public void setDates(List<Date> dates) {
        this.dates = dates;
    }

    public List<String> getSpecialPeriods() {
        return specialPeriods;
    }

    public void setSpecialPeriods(List<String> specialPeriods) {
        this.specialPeriods = specialPeriods;
    }

    public List<String> getDateStrs() {
        return dateStrs;
    }

    public void setDateStrs(List<String> dateStrs) {
        this.dateStrs = dateStrs;
    }

    public void addDate(Date date) {
        this.dates.add(date);
    }

    public void addSpecialPeriod(String specialPeriod) {
        this.specialPeriods.add(specialPeriod);
    }

    public void addDate(String date) {
        this.dateStrs.add(date);
    }

}
package com.key.win.dgt;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;

import com.key.win.utils.DateUtils;
import com.key.win.vo.MyTime;
import com.key.win.vo.TimeVo;


public class TimeCallTest {

    public static void main(String[] args) throws Exception {
        List<TimeVo> times = new ArrayList<TimeVo>();
        TimeVo timeVo1 = new TimeVo();
        times.add(timeVo1);
        //5- 9
        createTime(0, 4, timeVo1);
        timeVo1.addSpecialPeriod("08:00-9:30");

        TimeVo timeVo2 = new TimeVo();
        times.add(timeVo2);
        //6-12
        createTime(1, 7, timeVo2);
        timeVo2.addSpecialPeriod("08:30-12:30");
        //timeVo2.addSpecialPeriod("15:30-19:30");

        TimeVo timeVo3 = new TimeVo();
        times.add(timeVo3);
        //10-17
        createTime(5, 12, timeVo3);
        timeVo3.addSpecialPeriod("11:00-14:00");

        TimeVo timeVo4 = new TimeVo();
        //times.add(timeVo4);
        //5-15
        createTime(0, 10, timeVo4);

        System.out.println("-----------------------------end--------------------");
        Map<String, Set<String>> days = TimeCallTest.splitDateTime(times);
        Map<String, Set<String>> everyDays = TimeCallTest.getEveryDay(days);
        Map<String, Set<String>> sortedMap = TimeCallTest.sortHashMap(everyDays);
        List<TimeVo> outTimes = TimeCallTest.unionDateTime(sortedMap);
        System.out.println(outTimes);

    }
    public static String forSet(Set<String> datetimes) {
        String datetimeNew = "";
        if (datetimes != null && datetimes.size() > 0) {
            Iterator<String> iDatetimes = datetimes.iterator();
            while (iDatetimes.hasNext()) {
                datetimeNew += iDatetimes.next();
            }
        }
        return datetimeNew;
    }

    public static List<TimeVo> unionDateTime(Map<String, Set<String>> sortedMap) throws Exception {
        // 把所有的日期放入list中
        List<String> keys = new ArrayList<String>(sortedMap.keySet());
        // 获取第一天的
        String dateStr = keys.get(0);
        // 将String 类型转化为日期类型,获取最小的第一天的
        Date dateStart = DateUtils.strToDate(dateStr);
        // 获取最后一个日期的
        Date dateEnd = DateUtils.strToDate(keys.get(keys.size() - 1));
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(dateStart);
        startCalendar.add(startCalendar.DATE, 1);

        Set<String> dateSets = new TreeSet<String>();
        // 获取最小的天的时段
        Set<String> times = sortedMap.get(dateStr);
        // 获取的是最小的天
        String dateSet = dateStr;
        String tiemStrs = forSet(times);
        for (; startCalendar.getTime().before(dateEnd) || startCalendar.getTime().equals(dateEnd); startCalendar.add(startCalendar.DATE, 1)) {
            // 获取下一天
            Date curDate = startCalendar.getTime();
            // 转为String
            String curDateStr = DateUtils.dateToStr(curDate);
            // 不为空,说明有这一天
            if (sortedMap.get(curDateStr) != null) {

                // 获取时段
                Set<String> curTimes = sortedMap.get(curDateStr);
                // 把时段拼接起来
                String curTiemStr = forSet(curTimes);
                // 两个时段如果相同,说明这两天用的是同一个时段
                if (curTiemStr.equals(tiemStrs) && StringUtils.isNotBlank(dateSet)) {
                    // 把同一个时段先标记起来
                    dateSet += "@" + curDateStr;

                } else {
                    // 否则,这两天不是同一个时段,就是不同的两个,直接放入
                    if(StringUtils.isNotBlank(dateSet) && StringUtils.isNotBlank(tiemStrs) ){
                        dateSets.add(dateSet);
                    }
                    dateSet = curDateStr;
                    tiemStrs = curTiemStr;

                }
            }else{
                // 否则,这两天不是同一个时段,就是不同的两个,直接放入
                if(StringUtils.isNotBlank(dateSet) && StringUtils.isNotBlank(tiemStrs) )
                    dateSets.add(dateSet);
                dateSet = "";
                tiemStrs = "";
            }

        }
        dateSets.add(dateSet);

         List<TimeVo> outTimes = new ArrayList<TimeVo>();
        Iterator<String> dateSetStrs = dateSets.iterator();
        while (dateSetStrs.hasNext()) {
            String idateStr = dateSetStrs.next();
            String[] splitStrs = idateStr.split("@");
            TimeVo tv = new TimeVo();
            String tvStartDate = splitStrs[0];
            Set<String> tvSet = sortedMap.get(tvStartDate);
            tv.addDate(tvStartDate);
            if (tvSet != null && tvSet.size() > 0) {
                List<String> tvSps = new ArrayList<String>(tvSet);

                tv.getSpecialPeriods().addAll(tvSps);
            }
            if (splitStrs.length > 1) {
                tv.addDate(splitStrs[splitStrs.length - 1]);
            }
            outTimes.add(tv);
        }
        return outTimes;
    }

    public static Map<String, Set<String>> sortHashMap(Map<String, Set<String>> everyDays) {
        Map<String, Set<String>> sortedMap = new LinkedHashMap<>();
        List<String> list = new ArrayList<String>();
        Iterator<String> item = everyDays.keySet().iterator();
        while (item.hasNext()) {
            list.add(item.next());
        }
        Collections.sort(list);
        Iterator<String> item2 = list.iterator();
        while (item2.hasNext()) {
            String key = item2.next();
            sortedMap.put(key, everyDays.get(key));
        }
        return sortedMap;
    }

    public static Map<String, Set<String>> splitDateTime(List<TimeVo> times) {
        Map<String, Set<String>> allDateTime = new HashMap<String, Set<String>>();
        for (int i = 0; i < times.size(); i++) {
            TimeVo vo = times.get(i);
            for (int j = 0; j < vo.getDates().size(); j++) {
                Date date = vo.getDates().get(j);
                String dateStr = DateUtils.dateToStr(date);
                Set<String> dateTimes = allDateTime.get(dateStr);
                if (dateTimes == null) {
                    dateTimes = new HashSet<String>();
                    allDateTime.put(dateStr, dateTimes);
                }
                if (vo.getSpecialPeriods() != null && vo.getSpecialPeriods().size() > 0) {
                    for (int m = 0; m < vo.getSpecialPeriods().size(); m++) {
                        String dateTime = vo.getSpecialPeriods().get(m);
                        //对日期做预期处理,比例不符合格式之类
                        dateTimes.add(dateTime);
                    }
                } else {
                    allDateTime.put(dateStr, new HashSet<String>());
                }

            }
        }
        return allDateTime;
    }

    public static Map<String, Set<String>> getEveryDay(Map<String, Set<String>> day) throws Exception {
        Map<String, Set<String>> everDay = new HashMap<>();
        for (Map.Entry<String, Set<String>> entry : day.entrySet()) {
            String date = entry.getKey();
            Set<String> times = entry.getValue();
            if (times != null && times.size() > 0) {
                //如果是一个元素就说明是一个时间段,不需要合计计算
                if (times.size() == 1) {
                    Set<String> oneTime = new TreeSet<String>();
                    oneTime.add(times.toArray(new String[1])[0]);
                    everDay.put(date, oneTime);
                } else if (times.size() > 1) {
                    everDay.put(date, new TreeSet<String>(TimeCallTest.unionTime(times)));
                }
            } else {
                //....
                everDay.put(date, new HashSet<String>());
            }

        }
        return everDay;
    }

    public static List<String> unionTime(Set<String> timeSet) throws Exception {
        List<MyTime> myTimeList = new ArrayList<MyTime>();
        Iterator<String> it = timeSet.iterator();
        Map<Integer, String> num2Str = new HashMap<Integer, String>();
        //拆分组装成MyTime格式
        while (it.hasNext()) {
            String str = (String) it.next();
            String[] startEndTimes = str.split("-");
            String startTime = startEndTimes[0];
            String endTime = startEndTimes[1];

            String startHM[] = startTime.split(":");
            int startMin = Integer.parseInt(startHM[0]) * 60 + Integer.parseInt(startHM[1]);
            num2Str.put(startMin, startTime);

            String endHM[] = endTime.split(":");
            int endMin = Integer.parseInt(endHM[0]) * 60 + Integer.parseInt(endHM[1]);
            num2Str.put(endMin, endTime);
            MyTime myTime = new MyTime(startMin, endMin);
            myTimeList.add(myTime);
        }

        Collections.sort(myTimeList);

        //System.out.println(myTimeList.size());
        //开时时间
        Stack<Integer> s = new Stack<Integer>();
        //结束时间
        Stack<Integer> e = new Stack<Integer>();
        s.push(0);
        e.push(0);
        for (MyTime time : myTimeList) {
            if (time.getStart() > time.getEnd()) {
                throw new Exception("The time is incorrect.");
            }
            if (time.getStart() > e.peek()) //没有交集
            {
                s.push(time.getStart());
                e.push(time.getEnd());
            } else if (time.getEnd() > (int) e.peek()) //有部分交集,取并集
            {
                e.pop();
                e.push(time.getEnd());
            }
            //else {} //完全被覆盖
        }
        List<String> dateTimes = new ArrayList<String>();
        while (!s.empty()) {
            String startStr = num2Str.get(s.pop());
            String endStr = num2Str.get(e.pop());
            if (startStr != null && !"".equals(startStr) && endStr != null && !"".equals(endStr)) {
                dateTimes.add(startStr + "-" + endStr);
            }
        }
        return dateTimes;

    }

    public static void createTime(int start, int end, TimeVo timeVo) {
        System.out.println("createTime----------------start----------------------");
        for (int i = start; i <= end; i++) {
            Calendar now = Calendar.getInstance();
            now.add(Calendar.DATE, i);
            timeVo.addDate(now.getTime());
            System.out.println("createTime----------------" + new SimpleDateFormat("yyyy-MM-dd").format(now.getTime()) + "----------------------");
        }
        System.out.println("createTime----------------end----------------------");
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值