/**
* Created by shun on 2020/12/3.
* 时间区间 计算算法 实现
* 时间段的插入
* 时间段的删除
*/
public class IntervalAlgorithm {
public static List<LocalDate[]> insertDate(List<LocalDate[]> intervals, LocalDate[] newInterval){
List<long[]> insert = insert(listToArray(intervals), new long[]{newInterval[0].toEpochDay(), newInterval[1].toEpochDay()});
return toDateList(insert);
}
public static List<LocalDate[]> removeDate(List<LocalDate[]> intervals, LocalDate[] toBeRemoved){
List<long[]> removed = removeInterval(listToArray(intervals), new long[]{toBeRemoved[0].toEpochDay(), toBeRemoved[1].toEpochDay()});
return toDateList(removed);
}
/**
* 插入新的时间区间
* @param intervals 已有区间
* @param newInterval 新区间
* @return 插入后的新区间
*/
public static List<long[]> insert(long[][] intervals, long[] newInterval) {
long left = newInterval[0];
long right = newInterval[1];
boolean placed = false;
List<long[]> ansList = new ArrayList<long[]>();
for (long[] interval : intervals) {
if (interval[0] > right) {
// 在插入区间的右侧且无交集
if (!placed) {
addInterval(ansList, new long[]{left, right});
placed = true;
}
addInterval(ansList, interval);
} else if (interval[1] < left) {
// 在插入区间的左侧且无交集
addInterval(ansList, interval);
} else {
// 与插入区间有交集,计算它们的并集
left = Math.min(left, interval[0]);
right = Math.max(right, interval[1]);
}
}
if (!placed) {
addInterval(ansList, new long[]{left, right});
}
// LocalDate[][] ans = new LocalDate[ansList.size()][2];
// for (int i = 0; i < ansList.size(); ++i) {
// ans[i] = ansList.get(i);
// }
return ansList;
}
/**
* 删除区间
* @param intervals
* @param toBeRemoved
* @return
*/
public static List<long[]> removeInterval(long[][] intervals, long[] toBeRemoved) {
List<long[]> res = new ArrayList();
for (long[] inter : intervals) {
if (inter[1] <= toBeRemoved[0] || inter[0] >= toBeRemoved[1]) {//不再区间就不变
addInterval(res, new long[]{inter[0], inter[1]});
} else {
//在区间
if (inter[0] < toBeRemoved[0] ) addInterval(res, new long[]{inter[0], toBeRemoved[0]});//右相交
if (inter[1] > toBeRemoved[1] ) addInterval(res, new long[]{toBeRemoved[1], inter[1]});//左相交
}
}
return res;
}
private static long[][] listToArray( List<LocalDate[]> list){
long[][] ans = new long[list.size()][2];
for (int i = 0; i < list.size(); ++i) {
ans[i] = new long[]{list.get(i)[0].toEpochDay(), list.get(i)[1].toEpochDay()};
}
return ans;
}
public static List<LocalDate[]> toDateList(List<long[]> array){
List<LocalDate[]> list = Lists.newArrayList();
for (int i = 0; i < array.size(); i++) {
list.add( new LocalDate[]{LocalDate.ofEpochDay(array.get(i)[0]), LocalDate.ofEpochDay(array.get(i)[1])});
}
return list;
}
//过滤掉当前时间以前的区间
private static void addInterval(List<long[]> list, long[] newInterval){
if (newInterval[1] > LocalDate.now().toEpochDay() ){
if (newInterval[0] < LocalDate.now().toEpochDay()) {
newInterval[0] = LocalDate.now().toEpochDay();
}
list.add(newInterval);
}
}
public static void main(String[] args) {
List<LocalDate[]> removeInterval = IntervalAlgorithm.removeDate(
Lists.newArrayList(
new LocalDate[]{LocalDate.of(2019, 01, 01), LocalDate.of(2020, 03, 01)},
new LocalDate[]{LocalDate.of(2021, 01, 01), LocalDate.of(2021, 03, 01)},
new LocalDate[]{LocalDate.of(2021, 05, 01), LocalDate.of(9999, 01, 01)}
),
new LocalDate[]{LocalDate.of(2021, 06, 01), LocalDate.of(9999, 01, 01)}
);
System.out.println(JSON.toJSONString(removeInterval));
List<LocalDate[]> insert = IntervalAlgorithm.insertDate(
removeInterval,
new LocalDate[]{LocalDate.of(2021, 06, 01), LocalDate.of(9999, 01, 01)});
System.out.println(JSON.toJSONString(insert));
}
}