遇到业务需求这样的原型图
而我又无法从数据库层面进行筛选只能在业务层,查出全量数据进行过滤
为了有通用性所以设计了一个工具类
我的需要根据条件过滤的时间属性是String类型的
/**
* 过滤在时间节点内的List
*
* @author lp
* @since 2023-10-18
*/
@Slf4j
@Component
public class FindDataUtil {
private LocalDate todayTime;//计算出来需要比较的尾时间
private LocalDate time;//计算出来需要比较的头时间
private String START_TIME;//需要进行比较的时间名
public FindDataUtil() {
}
/**
* 对时间进行筛选除符合时间条件的集合
*
* @param timeInterval 时间间隔 1 (一周), 2 (一月) ,3 (三月),4 (半年) null(全部)
* @param listNew 需要过滤的List
* @param clazz List中元素类型的字节码文件
* @param startTIme 需要进行过滤的时间 格式必须是(2023-10-18) 并且注意不能传null进来可以在外面将null替换成空串
* @param <T> 传入List的类型
* @return 过滤后在时间段内的集合
*/
public <T> List<T> mappingTimeInterval(String timeInterval, List<T> listNew, Class<T> clazz, String startTIme) {
this.todayTime = LocalDate.now();
switch (timeInterval) {
//1 (一周内)
case "1":
//一周前的时间
this.time = todayTime.minusDays(7);
return this.obtainDataTheTimeONTodayTime(listNew, clazz, startTIme);
// 2 (一月内)
case "2":
//一月前的时间
this.time = todayTime.minusMonths(1);
return this.obtainDataTheTimeONTodayTime(listNew, clazz, startTIme);
//3 (三月内)
case "3":
//三月前的时间
this.time = todayTime.minusMonths(3);
return this.obtainDataTheTimeONTodayTime(listNew, clazz, startTIme);
//4 (半年内)
case "4":
//半年前的时间
this.time = todayTime.minusMonths(6);
return this.obtainDataTheTimeONTodayTime(listNew, clazz, startTIme);
default:
//全部数据
this.time = null;
return this.obtainDataTheTimeONTodayTime(listNew, clazz, startTIme);
}
}
/**
* 自定义时间赛选
*
* @param listNew 需要筛选的集合
* @return 筛选后的集合
*/
private <T> List<T> obtainDataTheTimeONTodayTime(List<T> listNew, Class<T> clazz, String startTIme) {
//如果 time == null 说明没有匹配到不需要过滤
if (null == this.time) return listNew;
//list不为null
if (null == listNew) return null;
//字节码对象不能为null
if (null == clazz) return null;
//过滤条件不能为null
if (null == startTIme) return null;
this.START_TIME = startTIme;
//初始化List
List<T> resultList = new ArrayList<>();
//获取集合迭代器并获取他的元素类型
Object item = listNew.iterator().next();
try {
//判断对象和传入字节码对象是否一样
if (clazz == item.getClass()) {
//利用反射获取需要过滤条件的name
Field startTimeName = clazz.getDeclaredField(START_TIME);
//传入的实体类有这个字段
if (START_TIME.equals(startTimeName.getName())) {
//遍历集合找到对应的字段开始过滤
resultList = listNew.stream().filter(x ->
{
//确保可以访问私有的属性
startTimeName.setAccessible(true);
String startTimeValue = null;
try {
startTimeValue = startTimeName.get(x).toString();
} catch (Exception e) {
log.info("工具类FindDataUtil抛出错误{}", e);
return false;
}
//值不能为null并且长度大于10
if (startTimeValue == null && startTimeValue.length() < 10) return false;
if (this.time.isBefore(LocalDate.parse(startTimeValue.substring(0, 10)))
&& this.todayTime.isAfter(LocalDate.parse(startTimeValue.substring(0, 10)))
) {
return true;
} else {
return false;
}
}
).collect(Collectors.toList());
}
}
} catch (Exception e) {
log.info("工具类FindDataUtil抛出错误{}", e);
}
return resultList;
}
}
使用示例这里我是根据实体类里面的 requestTime 属性当过滤条件的
@Resource
private FindDataUtil f;
public List<CheckOrderDetail> checkOrderlist(VisitNoDto visitNoDto) {
JSONArray jsonArray = dmoUtil.checkOrderList(visitNoDto);
List<CheckOrderDetail> checkOrderDetailListOld = jsonArray.toJavaList(CheckOrderDetail.class);
//根据申请时间倒序排序
List<CheckOrderDetail> checkOrderDetailList = checkOrderDetailListOld.stream().sorted(Comparator.comparing(CheckOrderDetail::getRequestTime).reversed()).collect(Collectors.toList());
//调用工具类过滤出在时间节点内人数据
checkOrderDetailList = f.mappingTimeInterval(visitNoDto.getTimeInterval(), checkOrderDetailList, CheckOrderDetail.class, "requestTime");
return checkOrderDetailList;
}