最近在做一个数据图表展示的功能,显示订单近七天或者近半月的数量和金额。可以理解成下图所示的样子:
我是用枚举和集合的stream方法实现的数据初始化和组装,枚举用来动态初始化时间范围,集合的stream方法来将初始化的数据转换成map,以日期为key,然后查询数据库的数据组装到map中,组转完后返回数据即可。我觉得这个方法不错,特此记录一下。
流程如下:
模拟代码如下:
/**
* 订单汇总测试
*/
public class TransinfoSum {
public static void main(String[] args) {
// 模拟传参,前端传递显示近七天还是近半月,和枚举呼应
int code = 1;
// 初始化,根据code初始化日期范围
List<Transinfo> transinfoList = new ArrayList<Transinfo>();
for (int t=0; t<TimeTypeEnum.getTimeTypeEnum(code).getNum(); t++) {
// 从当前日期往前减t
transinfoList.add(new Transinfo(DateUtils.dateTime(DateUtils.addDays(new Date(), -t))));
}
// list转map
Map<String, Transinfo> transinfoMap = transinfoList.stream().collect(Collectors.toMap(Transinfo::getDate, transinfo -> transinfo));
// 模拟数据库数据
List<Transinfo> transinfoListFromDB = new ArrayList<Transinfo>();
// 开始组装数据
for (Transinfo transinfo : transinfoListFromDB) {
String date = transinfo.getDate();
transinfoMap.get(date).setNum(transinfo.getNum());
transinfoMap.get(date).setAmount(transinfo.getAmount());
}
// 返回数据即可
}
}
初始化后的数据是这样的:
Transinfo{date='2023-11-03', num=0, amount=0}
Transinfo{date='2023-11-02', num=0, amount=0}
Transinfo{date='2023-11-01', num=0, amount=0}
Transinfo{date='2023-10-31', num=0, amount=0}
Transinfo{date='2023-10-30', num=0, amount=0}
Transinfo{date='2023-10-29', num=0, amount=0}
Transinfo{date='2023-10-28', num=0, amount=0}
全部代码如下:
/**
* 枚举类,定义时间类型
*/
public enum TimeTypeEnum {
WEEK(1, "近七天", 7),
FIFTEEN(2, "近半月", 15),
MONTH(3, "近一月", 30);
private int code;
private String msg;
private int num;
TimeTypeEnum(int code, String msg, int num) {
this.code = code;
this.msg = msg;
this.num = num;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
public int getNum() {return num;}
public static TimeTypeEnum getTimeTypeEnum(int code) {
for (TimeTypeEnum timeTypeEnum : TimeTypeEnum.values()) {
if (code == timeTypeEnum.getCode()) {
return timeTypeEnum;
}
}
return null;
}
}
/**
* 订单汇总
*/
public class Transinfo {
public Transinfo(){}
public Transinfo(String date){
this.date = date;
this.num = 0;
this.amount = BigDecimal.ZERO;
}
private String date;
private Integer num;
private BigDecimal amount;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
@Override
public String toString() {
return "Transinfo{" +
"date='" + date + '\'' +
", num=" + num +
", amount=" + amount +
'}';
}
}
/**
* 订单汇总测试
*/
public class TransinfoSum {
public static void main(String[] args) {
// 模拟传参
int code = 1;
// 初始化
List<Transinfo> transinfoList = new ArrayList<Transinfo>();
for (int t=0; t<TimeTypeEnum.getTimeTypeEnum(code).getNum(); t++) {
transinfoList.add(new Transinfo(DateUtils.dateTime(DateUtils.addDays(new Date(), -t))));
}
// list转map
Map<String, Transinfo> transinfoMap = transinfoList.stream().collect(Collectors.toMap(Transinfo::getDate, transinfo -> transinfo));
// 模拟数据库数据
List<Transinfo> transinfoListFromDB = new ArrayList<Transinfo>();
// 开始组装数据
for (Transinfo transinfo : transinfoListFromDB) {
String date = transinfo.getDate();
transinfoMap.get(date).setNum(transinfo.getNum());
transinfoMap.get(date).setAmount(transinfo.getAmount());
}
// 返回数据即可
}
}
package com.exam.common.utils;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils;
/**
* 时间工具类
*
* @author ruoyi
*/
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
public static String YYYY = "yyyy";
public static String YYYY_MM = "yyyy-MM";
public static String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
private static String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
/**
* 获取当前Date型日期
*
* @return Date() 当前日期
*/
public static Date getNowDate()
{
return new Date();
}
/**
* 获取当前日期, 默认格式为yyyy-MM-dd
*
* @return String
*/
public static String getDate()
{
return dateTimeNow(YYYY_MM_DD);
}
public static final String getTime()
{
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
}
public static final String dateTimeNow()
{
return dateTimeNow(YYYYMMDDHHMMSS);
}
public static final String dateTimeNow(final String format)
{
return parseDateToStr(format, new Date());
}
public static final String dateTime(final Date date)
{
return parseDateToStr(YYYY_MM_DD, date);
}
public static final String parseDateToStr(final String format, final Date date)
{
return new SimpleDateFormat(format).format(date);
}
public static final Date dateTime(final String format, final String ts)
{
try
{
return new SimpleDateFormat(format).parse(ts);
}
catch (ParseException e)
{
throw new RuntimeException(e);
}
}
/**
* 日期路径 即年/月/日 如2018/08/08
*/
public static final String datePath()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyy/MM/dd");
}
/**
* 日期路径 即年/月/日 如20180808
*/
public static final String dateTime()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyyMMdd");
}
/**
* 日期型字符串转化为日期 格式
*/
public static Date parseDate(Object str)
{
if (str == null)
{
return null;
}
try
{
return parseDate(str.toString(), parsePatterns);
}
catch (ParseException e)
{
return null;
}
}
/**
* 获取服务器启动时间
*/
public static Date getServerStartDate()
{
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
return new Date(time);
}
/**
* 计算相差天数
*/
public static int differentDaysByMillisecond(Date date1, Date date2)
{
return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
}
/**
* 计算时间差
*
* @param endDate 最后时间
* @param startTime 开始时间
* @return 时间差(天/小时/分钟)
*/
public static String timeDistance(Date endDate, Date startTime)
{
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - startTime.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
long hour = diff % nd / nh;
// 计算差多少分钟
long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return day + "天" + hour + "小时" + min + "分钟";
}
/**
* 增加 LocalDateTime ==> Date
*/
public static Date toDate(LocalDateTime temporalAccessor)
{
ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
return Date.from(zdt.toInstant());
}
/**
* 增加 LocalDate ==> Date
*/
public static Date toDate(LocalDate temporalAccessor)
{
LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
return Date.from(zdt.toInstant());
}
}