在某些常见的图形、表格统计系统中,往往需要计算同比、环比等等,下面是自己整理的常用统计工具类方法
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.regex.Pattern;
/**
* 统计项目的工具类
*
* @author linmin
**/
public class StatisticsUtils {
/**
* 判断一个字符串是不是全是数字的正则匹配规则
*/
private static Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)?$");
/**
* 日志记录对象
*/
private static final Logger logger = LoggerFactory.getLogger(StatisticsUtils.class);
private StatisticsUtils() {
}
/**
* 同比,环比均可用
* 获取增长率,保留四位小数
* 增长率=(本月数-上月数)/上月数×100%
* @param lastCount 上月的数据
* @param currentCount 本月的数据
* @return float
*/
public static String getGrowthRate(double lastCount, double currentCount) {
double growthRate;
if (lastCount == 0) {
growthRate = 1;
} else {
growthRate = (float) (currentCount - lastCount) / lastCount;
}
//保留4为小数
return String.format("%.4f", growthRate);
}
/**
* 获取占比
* @param molecular 分子
* @param denominator 分母
* @return 返回占比
*/
public static String getProportion(double molecular, double denominator) {
String proportion;
if (denominator == 0) {
proportion = "";
} else {
double pro = molecular / denominator;
proportion = String.format("%.4f", pro);
}
return proportion;
}
/**
* 把对象转换成双精度数据
* @param object object
* @return 双精度数据
*/
public static double getObjectToDouble(Object object) {
String str = String.valueOf(object).trim();
if (StringUtils.isEmpty(str)) {
return 0;
}
if (!isNumber(str)) {
throw new NumberFormatException("字符串里面不全是数字,不能转换");
}
return Double.parseDouble(str);
}
/**
* 把对象转换成字符串
* @param object object
* @return String
*/
public static String getObjectToString(Object object) {
if(object==null){
return "";
}
return String.valueOf(object).trim();
}
/**
* 判断一个字符串是不是全是数字
* @param string 判断是不是全数字的字符串
* @return 布尔值
*/
private static boolean isNumber(String string) {
if (StringUtils.isEmpty(string)) {
return false;
}
return pattern.matcher(string).matches();
}
/**
* 获取昨年和今年同比的数据
* @param thisYearList 今年的数据
* @param lastYearList 昨年的数据
* @return 同比数据集合
*/
public static List<Map<String, Object>> getYearOnYearList(List<Map<String, Object>> thisYearList, List<Map<String, Object>> lastYearList) {
//住院总费用同比增长集合
List<Map<String, Object>> yearOnYearZngeList = new ArrayList<>();
for (int i = 0; i < thisYearList.size(); i++) {
//获取今年每月对应的收入map
Map<String, Object> thisYearMap = thisYearList.get(i);
//获取去年每月对应的收入map
Map<String, Object> lastYearMap = lastYearList.get(i);
Object thisYearCost = thisYearMap.get("thisYearCost");
Object lastYearCost = lastYearMap.get("lastYearCost");
double thisYearCount = StatisticsUtils.getObjectToDouble(thisYearCost);
double lastYearCount = StatisticsUtils.getObjectToDouble(lastYearCost);
//根据去年和今年的总收入算出对应的增长率
String growthRate = StatisticsUtils.getGrowthRate(lastYearCount, thisYearCount);
//时间横坐标 1月、 2月……
String dateAbscissa = (String) thisYearMap.get("dateAbscissa");
//每次计算得出的增长率map
Map<String, Object> yearOnYearMap = new HashMap<>(16);
//吧每月对应的增长率放入map
yearOnYearMap.put("dateAbscissa", dateAbscissa);
yearOnYearMap.put("thisYearCount",thisYearCount);
yearOnYearMap.put("lastYearCount",lastYearCount);
yearOnYearMap.put("growthRate", growthRate);
yearOnYearZngeList.add(yearOnYearMap);
}
return yearOnYearZngeList;
}
/**
* 获取双精度数据的后几位数据
* @param d 双精度数据
* @param digit 需要保留小数点后几位
* @return 返回处理后的字符串对象
*/
public static String getNumberFormatByDecimalPlaces(double d, int digit) {
NumberFormat numberInstance = NumberFormat.getNumberInstance();
numberInstance.setMaximumFractionDigits(digit);
return numberInstance.format(d);
}
/**
* 获取上月环比日期
* @param date 本月日期
* @param formatPattern 日期的匹配格式
* @return 获取上月环比日期
*/
private static String getLastMouthDate( String date,String formatPattern){
Date lastMouth=new Date();
try {
SimpleDateFormat format = new SimpleDateFormat(formatPattern);
Date currentDate = format.parse(date);
Calendar c = Calendar.getInstance();
c.setTime(currentDate);
c.add(Calendar.MONTH, -1);
lastMouth = c.getTime();
} catch (ParseException e) {
logger.error("获取环比日期异常",e);
}
return format(lastMouth,formatPattern);
}
/**
* 获取去年同比日期
* @param date 今年对应的日期
* @param formatPattern 日期的匹配格式
* @return 获取去年同比日期
*/
public static String getLastYearDate( String date,String formatPattern){
Date lastYear=new Date();
try {
SimpleDateFormat format = new SimpleDateFormat(formatPattern);
Date currentDate = format.parse(date);
Calendar c = Calendar.getInstance();
c.setTime(currentDate);
c.add(Calendar.YEAR, -1);
lastYear = c.getTime();
} catch (ParseException e) {
logger.error("获取同比日期异常",e);
}
return format(lastYear,formatPattern);
}
/**
* 格式化时间成字符串
* @param time 需要格式化的时间
* @param formatPattern 日期的匹配格式
* @return 返回对应格式的时间字符串
*/
private static String format(Date time,String formatPattern) {
SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);
return sdf.format(time);
}
/**
* 获取上期环比搜索条件(移除以前的时间参数值)
* @param searchConditionalParameters 搜索条件map
* @param startDate 开始时间
* @param endDate 结束时间
*/
public static Map<String, Object> replaceLastMouthConditional( Map<String, Object> searchConditionalParameters,String startDate ,String endDate ){
searchConditionalParameters.remove(Constant.START_DATE.getDescribe());
searchConditionalParameters.remove(Constant.END_DATE.getDescribe());
searchConditionalParameters.put(Constant.START_DATE.getDescribe(),StatisticsUtils.getLastMouthDate(startDate,Constant.DATE_FORMAT_PATTERN.getDescribe()));
searchConditionalParameters.put(Constant.END_DATE.getDescribe(),StatisticsUtils.getLastMouthDate(endDate,Constant.DATE_FORMAT_PATTERN.getDescribe()));
return searchConditionalParameters;
}
/**
* 获去年同比搜索条件(移除以前的时间参数值)
* @param searchConditionalParameters 搜索条件map
* @param startDate 开始时间
* @param endDate 结束时间
*/
public static Map<String, Object> replaceLastYearConditional( Map<String, Object> searchConditionalParameters,String startDate ,String endDate ){
searchConditionalParameters.remove(Constant.START_DATE.getDescribe());
searchConditionalParameters.remove(Constant.END_DATE.getDescribe());
searchConditionalParameters.put(Constant.START_DATE.getDescribe(),StatisticsUtils.getLastYearDate(startDate,Constant.DATE_FORMAT_PATTERN.getDescribe()));
searchConditionalParameters.put(Constant.END_DATE.getDescribe(),StatisticsUtils.getLastYearDate(endDate,Constant.DATE_FORMAT_PATTERN.getDescribe()));
return searchConditionalParameters;
}
/**
* 获取开始时间,如果没有传入时间,则默认当年的1月1日
* @param request 客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息
* @return 开始时间字符串
*/
public static String getStartDate(HttpServletRequest request){
String startDate = request.getParameter(Constant.START_DATE.getDescribe());
LocalDate localDate=LocalDate.now();
if (StringUtils.isEmpty(startDate)){
startDate=localDate.getYear()+"-01-01";
}
return startDate;
}
/**
* 获取结束时间,如果没有传入时间,则默认当前时间
* @param request 客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息
* @return 结束时间字符串
*/
public static String getEndDate(HttpServletRequest request){
String endDate = request.getParameter(Constant.END_DATE.getDescribe());
LocalDate localDate=LocalDate.now();
if (StringUtils.isEmpty(endDate)){
endDate=localDate.toString();
}
return endDate;
}
}