java 如何计算同比增长工具类

作者:FanClys 时间:2023-11-09 08:50:35 

java 计算同比增长工具类

为了数据的严谨性,统一装换为BigDecimal,话不多说,看代码。


package com.pig4cloud.pigx.admin.api.util;
import java.math.BigDecimal;
public class PercentCount {
public String percentBigDecimal(BigDecimal preNum,BigDecimal sufNum){
double result = countDecimal(preNum,sufNum);
if(result>0){
return "+"+result+"%";
}
if(result<0){
return result+"%";
}
if(result==0){
return "+"+0+"%";
}
return null;
}
public  double countDecimal(BigDecimal preNum,BigDecimal sufNum){
boolean preBoolean = verifyNum(preNum);
boolean sufBoolean = verifyNum(sufNum);
//同时为true计算
if(preBoolean && sufBoolean){
boolean b = verifyEqual(preNum, sufNum);
if (b == false){
return realCountDecimal(preNum,sufNum);
}
if (b){
return 0;
}
}
if(preBoolean == false && sufBoolean ==false){
return 0;
}
if(sufBoolean ==false){
return 100;
}
return  0;
}
//验证数字是否为零和null
public boolean verifyNum(BigDecimal num){
if(null !=num && num.compareTo(BigDecimal.ZERO)!=0 ){
return true;
}
return false;
}
//验证两个数字是否相等
public boolean verifyEqual(BigDecimal preNum,BigDecimal sufNum){
int n = preNum.compareTo(sufNum);
//比较 -1 小于   0 等于    1 大于
if(n==0){
return true;
}
return false;
}
//真正计算
public double realCountDecimal(BigDecimal preNum,BigDecimal sufNum){
//(前面的数字-后面的数字)/后面的数字*100
BigDecimal bigDecimal = (preNum.subtract(sufNum)).divide(sufNum).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_UP);
if (bigDecimal.compareTo(BigDecimal.ZERO) !=0){
return  bigDecimal.doubleValue();
}
return 0;
}
public static void main(String[] args) {
PercentCount p = new PercentCount();
BigDecimal a = new BigDecimal("3");
BigDecimal b = new BigDecimal("1");
String percent = p.percentBigDecimal(a, b);
System.out.println(percent);
}
}

Java计算同比环比

同比环比计算基本概念和计算公式

同比率:本年数据比上一年数据增长或减少的比率

同比率计算公式:rate = (本年数据 - 前一年数据) / 前一年数据

实例:2020年10月游客数量为80W,2019年10月游客数量为100W,2018年10月游客数量为90W

2020年同比率为:rate :(80 - 100)/100 * 100%= -20%

2019年同比率为:rate :(100 - 900)/900 * 100%= +11%

(“+” 为增长,“-”为降低)

环比率:本月(季度)数据比上个月(季度)数据增长或减少的比率

环比率计算公式:rate = (本月数据 - 上个月数据) / 上个月数据

实例:2020年10月游客数量为100W,2020年9月游客数量为90W,2020年7月游客数量为80W

2020年10月同比率为:rate :(100 - 90)/90 * 100%= +11%

2019年10月同比率为:rate :(90- 80)/800 * 100%= +12.5%

注:同比环比计算公式是相同的,但计算数据对应的时间是不同的

代码实现逻辑

通过Calendar等时间函数和HashMap,[ hashmap(key,value) key为时间,value为该时间对应的值]。将key和value一一对应的存入集合中,通过对key进行操作,再用key获取HashMap中相对应的value,套公式计算(重点在于对时间(key)的操作,通过key可直接获取value进行计算)

详细逻辑步骤

首先通过SQL语句获取数据库中相应的时间和该时间对应的数据,按时间分组排序


SELECT
       DATAS.DATE AS NAME ,
       SUM( DATAS.VISITORSUM) AS VALUE,
       2 AS sfzj,
       '' AS bfb
       FROM
       (SELECT TOURIST.* ,CONCAT(YEAR,'年',QUARTER,'月') AS DATE
       FROM TOURISTFLOW TOURIST)DATAS
       GROUP BY DATAS.DATE
       ORDER BY DATAS.DATE

接着设置时间范围,将最早的时间减去一年设为最小时间,最后的时间为最大时间,以此为范围即可保证覆盖所有数据


// 设置时间范围
           // 获取最前的时间的第一个列表
           analyzeBean firstTimeSubway = analyzeByYear.get(0);
           String startTime = firstTimeSubway.getTime();
           // 获取最后时间的最后一个列表
           analyzeBean endTimeSubway = analyzeByYear.get(analyzeByYear.size() - 1);
           String endTime = endTimeSubway.getTime();
           // 时间格式转换
           SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月");
           Date parse = format.parse(startTime);
           Date parse1 = format.parse(endTime);
           Calendar c = Calendar.getInstance();
           c.setTime(parse);
           c.add(Calendar.YEAR, -1);
           Date y = c.getTime();
           // 获取最前的时间的前一年的时间作为查询范围
           String firstTime = format.format(y);
           analyzeRequestBean.setStartTime(firstTime);
           Calendar c1 = Calendar.getInstance();
           c1.setTime(parse1);
           Date y1 = c1.getTime();
           // 获取最后一年的时间作为查询范围
           String lastTime = format.format(y1);
           analyzeRequestBean.setStartTime(lastTime);

在将所有数据的结果集存入HashMap中 hash(key,value) key为时间,value为数据值


hashMap.put(time, analyzeByYear.get(i).getValue());

最后通过for循环和CaleCndar函数和Date函数对时间(key)进行相应的操作,再通过时间(key)到HashMap中找对应的值进行计算


for (int i = 0; i < analyzeByYear.size(); i++) {
               AnalyzeBean analyzeBean = analyzeByYear.get(i);
               if (i == 0) {
               // 是否增长("0:降低 1:增加 2:既不增长也不降低")
                   analyzeBean.setSfzj(2);
                   analyzeBean.setBfb(null);
               } else {
                   SimpleDateFormat format2 = new SimpleDateFormat("yyyy年MM月");
                   // 当前数据
                   Date parse2 = format2.parse(analyzeBean.getTime());
                   Calendar c2 = Calendar.gaetInstance();
                   c2.setTime(parse2);
                   c2.add(Calendar.YEAR, 0);
                   Date t = c2.getTime();
                   String time = format2.format(t);
                   Integer value = hashMap.get(time);
                   // 往年数据
                   Date parse3 = format2.parse(time);
                   Calendar c3 = Calendar.getInstance();
                   c3.setTime(parse3);
                   c3.add(Calendar.YEAR, -1);
                   Date year = c3.getTime();
                   String time1 = format2.format(year);
                   Integer value1 = hashMap.get(time1);
                   if (null != value1 && null != value) {
                       if (value.equals(value1)) {
                           analyzeBean.setSfzj(2);
                           analyzeBean.setBfb(null);
                       } else {
                           if (value > value1) {
                               analyzeBean.setSfzj(1);
                           } else {
                               analyzeBean.setSfzj(0);
                           }
                           // 2个值减法 绝对值
                           int abs = Math.abs(value - value1);
                           float a = (float) (abs) / (float) value1 * 100;
                           analyzeBean.setBfb(a + "");
                       }
                   } else {
                       analyzeBean.setSfzj(2);
                       analyzeBean.setBfb(null);
                   }
               }
           }

同比实例代码:


// 求同比
   @Override
   public Result getAnalyzeByYear(AnalyzeRequestBean analyzeRequestBean) {
       try {
           // 检查参数
           if (null == analyzeRequestBean) {
               return ResultUtil.fail(ResultEnum.PARAMS_ERROR);
           }
a
           List<AnalyzeBean> analyzeByYear
                   = InfoMapper.getAnalyzeByYear(analyzeRequestBean);
           if (analyzeByYear == null || analyzeByYear.size() == 0) {
               return ResultUtil.ok(null);
           }
           // 设置时间范围
           // 获取最前的时间的第一个列表
           analyzeBean firstTimeSubway = analyzeByYear.get(0);
           String startTime = firstTimeSubway.getTime();
           // 获取最后时间的最后一个列表
           analyzeBean endTimeSubway = analyzeByYear.get(analyzeByYear.size() - 1);
           String endTime = endTimeSubway.getTime();
           // 时间格式转换
           SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月");
           Date parse = format.parse(startTime);
           Date parse1 = format.parse(endTime);
           Calendar c = Calendar.getInstance();
           c.setTime(parse);
           c.add(CaleCndar.YEAR, -1);
           Date y = c.getTime();
           // 获取最前的时间的前一年的时间作为查询范围
           String firstTime = format.format(y);
           analyzeRequestBean.setStartTime(firstTime);
           Calendar c1 = Calendar.getInstance();
           c1.setTime(parse1);
           Date y1 = c1.getTime();
           // 获取最后一年的时间作为查询范围
           String lastTime = format.format(y1);
           analyzeRequestBean.setStartTime(lastTime);
           // 把大范围的结果集都放入hashMap中
           HashMap<String, Integer> hashMap = new HashMap<>();
           for (int i = 0; i < analyzeByYear.size(); i++) {
               analyzeBean analyzeBean = analyzeByYear.get(i);
               SimpleDateFormat format1 = new SimpleDateFormat("yyyy年MM月");
               Date parse2 = format1.parse(analyzeBean.getTime());
               Calendar c2 = Calendar.getInstance();
               c2.setTime(parse2);
               c2.add(Calendar.YEAR, 0);
               Date t = c2.getTime();
               String time = format1.format(t);
               hashMap.put(time, analyzeByYear.get(i).getValue());
           }
           for (int i = 0; i < analyzeByYear.size(); i++) {
               AnalyzeBean analyzeBean = analyzeByYear.get(i);
               if (i == 0) {
               // 是否增长("0:降低 1:增加 2:既不增长也不降低")
                   analyzeBean.setSfzj(2);
                   analyzeBean.setBfb(null);
               } else {
                   SimpleDateFormat format2 = new SimpleDateFormat("yyyy年MM月");
                   // 当前数据
                   Date parse2 = format2.parse(analyzeBean.getTime());
                   Calendar c2 = Calendar.gaetInstance();
                   c2.setTime(parse2);
                   c2.add(Calendar.YEAR, 0);
                   Date t = c2.getTime();
                   String time = format2.format(t);
                   Integer value = hashMap.get(time);
                   // 往年数据
                   Date parse3 = format2.parse(time);
                   Calendar c3 = Calendar.getInstance();
                   c3.setTime(parse3);
                   c3.add(Calendar.YEAR, -1);
                   Date year = c3.getTime();
                   String time1 = format2.format(year);
                   Integer value1 = hashMap.get(time1);
                   if (null != value1 && null != value) {
                       if (value.equals(value1)) {
                           analyzeBean.setSfzj(2);
                           analyzeBean.setBfb(null);
                       } else {
                           if (value > value1) {
                               analyzeBean.setSfzj(1);
                           } else {
                               analyzeBean.setSfzj(0);
                           }
                           // 2个值减法 绝对值
                           int abs = Math.abs(value - value1);
                           float a = (float) (abs) / (float) value1 * 100;
                           analyzeBean.setBfb(a + "");
                       }
                   } else {
                       analyzeBean.setSfzj(2);
                       analyzeBean.setBfb(null);
                   }
               }
           }
           return ResultUtil.ok(analyzeByYear);
       } catch (ParseException ex) {
           ex.printStackTrace();
       }
       return ResultUtil.ok(null);
   }

环比类似,只是把c.add(Calendar.YEAR, 0);换成c.add(Calendar.MONTH, 0)

实现逻辑其实不难,只是我写复杂了,如有更好的方法欢迎留言交流讨论

来源:https://blog.csdn.net/qq_42274641/article/details/98640070

标签:java,工具类
0
投稿

猜你喜欢

  • Unity3D生成一段隧道网格的方法

    2022-02-22 23:46:27
  • 解决java 分割字符串成数组时,小圆点不能直接进行分割的问题

    2023-11-05 03:13:24
  • C# 特殊的string类型详解

    2022-02-10 14:11:59
  • springboot-mongodb的多数据源配置的方法步骤

    2022-05-06 12:04:48
  • Spring Security 图片验证码功能的实例代码

    2023-11-17 14:23:56
  • 解决myBatis generator逆向生成没有根据主键的select,update和delete问题

    2022-05-13 06:18:56
  • 一文带你了解C#中的协变与逆变

    2022-08-06 22:31:21
  • MyBatis字段名和属性名不一致的解决方法

    2022-12-15 18:15:22
  • Spring中的两种代理JDK和CGLIB的区别浅谈

    2023-01-04 19:05:05
  • Spring IOC基于注解启动示例详析

    2022-04-19 22:49:55
  • SpringBoot项目@Async方法问题解决方案

    2023-11-12 03:55:26
  • Springboot公共字段填充及ThreadLocal模块改进方案

    2023-11-17 22:58:39
  • Springboot使用@Valid 和AOP做参数校验及日志输出问题

    2023-12-05 04:39:12
  • 深入了解Java Synchronized锁升级过程

    2021-12-12 08:13:45
  • javaWeb项目部署到阿里云服务器步骤详解

    2023-11-07 05:21:36
  • Spring boot集成Kafka消息中间件代码实例

    2022-11-06 21:53:48
  • Android仿微信语音消息的录制和播放功能

    2022-08-15 09:28:32
  • java状态机方案解决订单状态扭转示例详解

    2022-01-10 02:55:43
  • Java Valhalla Project项目介绍

    2021-10-03 00:29:28
  • Kotlin定义其他类的实现详解

    2022-12-18 09:29:14
  • asp之家 软件编程 m.aspxhome.com