栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

使用Java实现给绳子或线段描颜色的算法,基于时间轴的考勤计算算法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Java实现给绳子或线段描颜色的算法,基于时间轴的考勤计算算法

场景 要实现一个绳子染色的功能的算法
如图:

一开始是一个红色线段,两端坐标分别为0和100,画上一个蓝色线段后,红色线段被截断,变成红蓝红三个线段,可以重复染色,后来者覆盖,有多种颜色可以染色
线段集合是List ,要求尽可能用Java stream实现画新颜色的draw函数

这里我直接用时间线段进行演示,画图逻辑类似
实现方式如下
声明一个存储时间线段单元的类TeacherAttUnit ,并声明时间的类型枚举AttType

public class TeacherAttUnit {
	//考勤类型
	enum  AttType{

		WEI_CHU_QIN("未出勤","weichuqin",1),
		CHU_QIN("出勤","chuqin",2),
		NIAN_JIA("年假","nianjia",3),
		HUN_JIA("婚假","hunjia",4),
		SHI_JIA("事假","shijia",5);
		public final String name;  //此时段的考勤类型
		public final String attType;  //此时段的考勤类型
		public final int  sort;  //此时段的考勤类型
		AttType(String name,String attType,int sort) {
			this.name = name;
			this.attType = attType;
			this.sort = sort;
		}
		
		
	}
	
	public  Date startTime;  //开始时间
	public  Date endTime;   //结束时间
	public  AttType attType;  //此时段的考勤类型
	public  List attTypeList =new ArrayList<>();//所有出现的考勤类型
	public  String leaveType;//  假单类型
	public Date getStartTime() {
		return startTime;
	}
	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}
	public Date getEndTime() {
		return endTime;
	}
	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}
	public AttType getAttType() {
		return attType;
	}
	public void setAttType(AttType attType) {
		this.attType = attType;
	}
	public List getAttTypeList() {
		return attTypeList;
	}
	public void setAttTypeList(List attTypeList) {
		this.attTypeList = attTypeList;
	}
	public String getLeaveType() {
		return leaveType;
	}
	public void setLeaveType(String leaveType) {
		this.leaveType = leaveType;
	}
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "n"+ JSONObject.toJSONString(this);
	}
}

再声明一个实现算法的核心计算类,构造函数声明覆盖的时间轴和时间轴的初始化类型
每增加一个新的类型时间段,只需要调用insert方法插入即可

public class TeacherAttCalculationPress  {
	//这里防止调用者修改计算过程,声明为私有
	private List  attList; //每个时段的集合
	
	public TeacherAttCalculationPress(Date startTime,Date endTime,AttType attType, String leaveType){
		attList = new linkedList();
		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日  出勤
	
	public void insert(TeacherAttUnit attUnitNew) {
		if (attList == null) {
			attList = new linkedList();
		}
		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  flatList =  new  ArrayList<>();
			//以下处理只保留attNode覆盖的时段,所以要求alllist中第一个节点是覆盖全天的
			
			if (attNode.getStartTime().compareTo(attUnitNew.getEndTime()) >= 0
					||attNode.getEndTime().compareTo(attUnitNew.getStartTime()) <= 0) {
				flatList.add(attNode);
			}
			
			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);
			}
			
			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);
				}
				
			}
			
			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);
				}
				
			}
			
			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(),  (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);
	}
	
	public String  calculationResult() {
		
		return attList.toString();
	}
}

声明main函数进行测试

	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);
	}

测试结果

初始化时间轴》》[
{"attType":"WEI_CHU_QIN","attTypeList":["WEI_CHU_QIN"],"endTime":1633968000000,"leaveType":"","startTime":1633881600000}]
增加出勤》》[
{"attType":"WEI_CHU_QIN","attTypeList":["WEI_CHU_QIN"],"endTime":1633914000000,"startTime":1633881600000}, 
{"attType":"CHU_QIN","attTypeList":["WEI_CHU_QIN","CHU_QIN"],"endTime":1633935600000,"startTime":1633914000000}, 
{"attType":"WEI_CHU_QIN","attTypeList":["WEI_CHU_QIN"],"endTime":1633968000000,"startTime":1633935600000}]
增加交叉出勤》》[
{"attType":"WEI_CHU_QIN","attTypeList":["WEI_CHU_QIN"],"endTime":1633914000000,"startTime":1633881600000}, 
{"attType":"CHU_QIN","attTypeList":["WEI_CHU_QIN","CHU_QIN","CHU_QIN"],"endTime":1633946400000,"startTime":1633914000000}, 
{"attType":"WEI_CHU_QIN","attTypeList":["WEI_CHU_QIN"],"endTime":1633968000000,"startTime":1633946400000}]
增加年假》》[
{"attType":"WEI_CHU_QIN","attTypeList":["WEI_CHU_QIN"],"endTime":1633914000000,"startTime":1633881600000}, 
{"attType":"CHU_QIN","attTypeList":["WEI_CHU_QIN","CHU_QIN","CHU_QIN"],"endTime":1633939200000,"startTime":1633914000000}, 
{"attType":"NIAN_JIA","attTypeList":["WEI_CHU_QIN","CHU_QIN","CHU_QIN","NIAN_JIA"],"endTime":1633942800000,"startTime":1633939200000}, 
{"attType":"CHU_QIN","attTypeList":["WEI_CHU_QIN","CHU_QIN","CHU_QIN"],"endTime":1633946400000,"startTime":1633942800000}, 
{"attType":"WEI_CHU_QIN","attTypeList":["WEI_CHU_QIN"],"endTime":1633968000000,"startTime":1633946400000}]

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/314620.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号