场景 要实现一个绳子染色的功能的算法
如图:
点 对象 使用 String表示
线段对象 Line {
String start;
String end
}
线段集合是List ,要求尽可能用Java stream实现画新颜色的draw函数
一段线能否重复染色,是否只有红蓝两色,
已解决
/**
* 老师考勤计算过程
*
*/
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
* 考勤计算过程
* @author chenlinhui
*
*/
public class TeacherAttCalculationPress {
public static void main(String[] args) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date startDate = format.parse("2021-10-11 00:00:00");
Date endTime = format.parse("2021-10-12 00:00:00");
TeacherAttCalculationPress press = new TeacherAttCalculationPress(startDate, endTime, AttType.WEI_CHU_QIN, "");
System.err.println("初始化时间轴》》" + press.attList);
TeacherAttUnit attUnitNew1 = new TeacherAttUnit();
attUnitNew1.setStartTime(format.parse("2021-10-11 09:00:00"));
attUnitNew1.setEndTime(format.parse("2021-10-11 15:00:00"));
attUnitNew1.setAttType(AttType.CHU_QIN);
attUnitNew1.setLeaveType("");
press.insert(attUnitNew1);
System.err.println("增加出勤》》" + press.attList);
TeacherAttUnit attUnitNew = new TeacherAttUnit();
attUnitNew.setStartTime(format.parse("2021-10-11 12:00:00"));
attUnitNew.setEndTime(format.parse("2021-10-11 18:00:00"));
attUnitNew.setAttType(AttType.CHU_QIN);
attUnitNew.setLeaveType("");
press.insert(attUnitNew);
System.err.println("增加交叉出勤》》" + press.attList);
TeacherAttUnit attUnitNew2 = new TeacherAttUnit();
attUnitNew2.setStartTime(format.parse("2021-10-11 16:00:00"));
attUnitNew2.setEndTime(format.parse("2021-10-11 17:00:00"));
attUnitNew2.setAttType(AttType.NIAN_JIA);
attUnitNew2.setLeaveType("");
press.insert(attUnitNew2);
System.err.println("增加年假》》" + press.attList);
}
private List<TeacherAttUnit> attList; //每个时段的集合
/**
* 初始化计算过程
* @param startTime 时间轴开始时间
* @param endTime 时间轴结束时间
* @param attType 时间轴默认考勤状态
* @param leaveType 时间轴默认请假状态
*/
public TeacherAttCalculationPress(Date startTime,Date endTime,AttType attType, String leaveType){
attList = new LinkedList<TeacherAttUnit>();
TeacherAttUnit attTeacherAttUnit = new TeacherAttUnit();
attTeacherAttUnit.setStartTime(startTime);
attTeacherAttUnit.setEndTime(endTime);
attTeacherAttUnit.setAttType(attType);
attTeacherAttUnit.setLeaveType(leaveType);
attTeacherAttUnit.attTypeList.add(attType);
attList.add(attTeacherAttUnit);
}
//原有数据 2021年9月01日 到2021年9月29日 出勤
//插入数据 2021年9月09日 到 2021年9月19日 类型请假
//结果 2021年9月01日 到2021年9月29日 出勤, 2021年9月29日 到 2021年9月09日 请假, 2021年9月09日 到 2021年9月19日 出勤
/**
* 添加一个假单,第一个添加的假单时间区间是最大需要处理的时间区间
* @param attUnitNew 新加的考勤单元或者假单
*/
public void insert(TeacherAttUnit attUnitNew) {
if (attList == null) {
attList = new LinkedList<TeacherAttUnit>();
}
if (attList.size() == 0) {
attList.add(attUnitNew);
return;
}
//步骤1. 进行线段染色,染色后会出现相邻线段相同颜色情况,下一步需要合并
attList = attList.stream().flatMap((attNode)->{
SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss" );
List<TeacherAttUnit> flatList = new ArrayList<>();
//以下处理只保留attNode覆盖的时段,所以要求alllist中第一个节点是覆盖全天的
/**
* att ------------
* 情况一 └───────────────────────┘
* 互相无交叉
* */
if (attNode.getStartTime().compareTo(attUnitNew.getEndTime()) >= 0
||attNode.getEndTime().compareTo(attUnitNew.getStartTime()) <= 0) {
flatList.add(attNode);
}
/**
* att ------------
* 情况二 └───────────────────────┘
* 新的包含已有的
* */
else if (attUnitNew.getStartTime().compareTo(attNode.getStartTime()) <= 0
&& attUnitNew.getEndTime().compareTo(attNode.getEndTime()) >= 0) {
attNode.getAttTypeList().add(attUnitNew.attType);
if (attNode.getAttType().sort < attUnitNew.getAttType().sort) {
attNode.setAttType(attUnitNew.attType);
}
flatList.add(attNode);
}
/**
* att ------------------------------
* 情况三 └──────────────┘
* 已有的包含新的
* */
else if (attUnitNew.getStartTime().compareTo(attNode.getStartTime()) > 0
&& attUnitNew.getEndTime().compareTo(attNode.getEndTime()) < 0) {
if (attNode.getAttType().sort < attUnitNew.getAttType().sort) {
//新插入优先级高,时间段被分割成三个时间段
TeacherAttUnit attNew_1 = new TeacherAttUnit();
attNew_1.setStartTime(attNode.getStartTime());
attNew_1.setEndTime(attUnitNew.getStartTime());
attNew_1.setAttType(attNode.getAttType());
attNew_1.getAttTypeList().addAll(attNode.attTypeList);
TeacherAttUnit attNew_2 = new TeacherAttUnit();
attNew_2.setStartTime(attUnitNew.getStartTime());
attNew_2.setEndTime(attUnitNew.getEndTime());
attNew_2.setAttType(attUnitNew.getAttType());
attNew_2.getAttTypeList().addAll(attNode.attTypeList);
attNew_2.getAttTypeList().add(attUnitNew.attType);
TeacherAttUnit attNew_3 = new TeacherAttUnit();
attNew_3.setStartTime(attUnitNew.getEndTime());
attNew_3.setEndTime(attNode.getEndTime());
attNew_3.setAttType(attNode.getAttType());
attNew_3.getAttTypeList().addAll(attNode.attTypeList);
flatList.add(attNew_1);
flatList.add(attNew_2);
flatList.add(attNew_3);
}else {
//保持不变
attNode.getAttTypeList().add(attUnitNew.attType);
flatList.add(attNode);
}
}
/**
* att ------------------------------
* 情况四 └───────────────────────┘
* 交叉一
* */
else if (attUnitNew.startTime.compareTo(attNode.startTime) <= 0
&& attUnitNew.endTime.compareTo(attNode.startTime) > 0
&& attUnitNew.endTime.compareTo(attNode.endTime) < 0) {
if (attNode.getAttType().sort < attUnitNew.getAttType().sort) {
//新插入优先级高,时间段被分割成两个时间段
TeacherAttUnit attNew_2 = new TeacherAttUnit();
attNew_2.setStartTime(attNode.getStartTime());
attNew_2.setEndTime(attUnitNew.getEndTime());
attNew_2.setAttType(attUnitNew.getAttType());
attNew_2.getAttTypeList().addAll(attNode.attTypeList);
attNew_2.getAttTypeList().add(attUnitNew.attType);
TeacherAttUnit attNew_3 = new TeacherAttUnit();
attNew_3.setStartTime(attUnitNew.getEndTime());
attNew_3.setEndTime(attNode.getEndTime());
attNew_3.setAttType(attNode.getAttType());
attNew_3.getAttTypeList().addAll(attNode.attTypeList);
flatList.add(attNew_2);
flatList.add(attNew_3);
}else {
//保持不变
attNode.getAttTypeList().add(attUnitNew.attType);
flatList.add(attNode);
}
}
/**
* att ------------------------------
* 情况五 └───────────────────────┘
* 交叉二
* */
else if (attUnitNew.startTime.compareTo(attNode.startTime) > 0
&& attUnitNew.startTime.compareTo(attNode.endTime) < 0
&& attUnitNew.endTime.compareTo(attNode.endTime) >= 0) {
if (attNode.getAttType().sort < attUnitNew.getAttType().sort) {
//新插入优先级高,时间段被分割成两个时间段
TeacherAttUnit attNew_3 = new TeacherAttUnit();
attNew_3.setStartTime(attNode.getStartTime());
attNew_3.setEndTime(attUnitNew.getStartTime());
attNew_3.setAttType(attNode.getAttType());
attNew_3.getAttTypeList().addAll(attNode.attTypeList);
TeacherAttUnit attNew_2 = new TeacherAttUnit();
attNew_2.setStartTime(attUnitNew.getStartTime());
attNew_2.setEndTime(attNode.getEndTime());
attNew_2.setAttType(attUnitNew.getAttType());
attNew_2.getAttTypeList().addAll(attNode.attTypeList);
attNew_2.getAttTypeList().add(attUnitNew.attType);
flatList.add(attNew_2);
flatList.add(attNew_3);
}else {
//保持不变
attNode.getAttTypeList().add(attUnitNew.attType);
flatList.add(attNode);
}
}
return flatList.stream();
})
//步骤2.排序,为 合并相邻的相同颜色的线段 做准备
.sorted((sortNode1,sortNode2) -> {
//按时间排序
return sortNode1.getStartTime().compareTo(sortNode2.getStartTime());
})
//步骤3:使用规约方法,比较相邻元素,进行合并操作
.reduce(new ArrayList<TeacherAttUnit>(), (result,attNode)->{
//跟最后一个元素相同就合并,不同就添加
if (result.size() >0 && result.get(result.size() - 1).attType.sort == attNode.attType.sort) {
//合并操作,也就是修改最后一个节点结束时间,
result.get(result.size() - 1).setEndTime(attNode.getEndTime());
}else {
result.add(attNode);
}
return result;
},(a,b) -> a);
}
/**
* 计算并返回考勤结果
* @return 计算完的考勤结果
*/
public String calculationResult() {
return attList.toString();
}
}