java 红包规则
java 红包规则
拼手气红包:
规则:最大金额:全部金额/个数*倍数
最小金额:0.01
最后一个红包是全部金额-领取金额
随机分配
package com.utils; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* 红包分发工具类
*
*/
public class CashRedPackUtils {
/**
* 一个红包最少拆分数量
*/
public static final int REDPACK_MIN_QUANTITY = 1;
/**
* 一个红包最多拆分数量
*/
public static final int REDPACK_MAX_QUANTITY = 100;
/**
* 小数位长度
*/
private static final int SCALE = 2;
/**
* 舍弃的小数位处理方式
*/
private static final RoundingMode ROUNDING_MODE = RoundingMode.HALF_EVEN;
/**
* 红包放大倍数
*/
private static final BigDecimal TIMES = new BigDecimal("3");
/**
* 单个红包最小金额
*/
public static final BigDecimal SINGLE_RED_MIN_MONEY = new BigDecimal("0.01");
/**
* 单个红包最大金额
*/
// private static final BigDecimal SINGLE_RED_MAX_MONEY = new BigDecimal("100");
/**
* 递归计算红包金额时连续错误最大值,超过此次数将返回最小值
*/
private static final int ERROR_MAX_NUM = 5;
/**
* 递归计算红包金额连续错误次数初始值
*/
private static final int ERROR_INIT_NUM = 1;
/**
* 计算金额时的小数位,1000代表3位小数
*/
private static final int FRACTION_LENGTH = 1000; /**
* 分发红包
* @param redMoney 红包总金额
* @param num 红包数量
* @return
*/
public static List<BigDecimal> SplitRedPackes(BigDecimal redMoney, int num) {
List<BigDecimal> redInfoList = new ArrayList<>();
// 红包有误
if(num < REDPACK_MIN_QUANTITY || num > REDPACK_MAX_QUANTITY)
return redInfoList; //校验:金额大于0
if(redMoney.compareTo(BigDecimal.ZERO) != 1) {
return redInfoList;
} if(num <= 1) {
redInfoList.add(redMoney);
return redInfoList;
}
Random random = new Random();
for(int i = 0; i < num; i++) {
// System.out.println("\n" + (i+1) + "个红包信息:");
int surplusNum = num - i;//未分配金额红包数量
BigDecimal curRedMoney = fightLuckRedPacked(redMoney, surplusNum, random, ERROR_INIT_NUM);
redInfoList.add(curRedMoney);
redMoney = redMoney.subtract(curRedMoney);
// MandoAssert.notTrue(redMoney.compareTo(BigDecimal.ZERO) == -1, "红包金额有误");
// System.out.println("红包金额:" + curRedMoney + ",剩余:" + redMoney);
}
return redInfoList;
} /**
* 拼手气红包
* @param redMoney 红包金额
* @param num 红包数量
* @param random 随机数生成对象
* @param errorNum 错误测试
* @return 单个红包金额
*/
private static BigDecimal fightLuckRedPacked(BigDecimal redMoney, int num, Random random, int errorNum) {
if(num <= 1) {
return redMoney;
}
if(errorNum > ERROR_MAX_NUM) {
//随机金额产生错误次数超过上限,返回最小值
return SINGLE_RED_MIN_MONEY;
}
//每个红包最大金额 = 剩余总金额 / 未分配金额红包数量 * 红包放大倍数
int avgRedMaxMoney = redMoney.divide(new BigDecimal(num), ROUNDING_MODE).multiply(TIMES).intValue() * FRACTION_LENGTH;
BigDecimal curRedMoney = new BigDecimal(random.nextInt(avgRedMaxMoney) * 1.00 / FRACTION_LENGTH + "").setScale(SCALE, ROUNDING_MODE);
if(curRedMoney.compareTo(SINGLE_RED_MIN_MONEY) == -1) {
//红包最小值判断:小于最小红包金额,重新计算
return fightLuckRedPacked(redMoney, num, random, ++errorNum);
}
/*if(curRedMoney.compareTo(SINGLE_RED_MAX_MONEY) == 1) {
//红包最大值判断
return fightLuckRedPacked(curRedMoney, num, random, ++errorNum);
}*/
//最少保留红包金额
BigDecimal surplusMinRedMoney = SINGLE_RED_MIN_MONEY.multiply(new BigDecimal(num - 1));
//除当前红包剩余金额
BigDecimal surplusRedMoney = redMoney.subtract(curRedMoney);
if(surplusMinRedMoney.compareTo(surplusRedMoney) == 1) {
return fightLuckRedPacked(redMoney, num, random, ++errorNum);
}
return curRedMoney;
} public static void main(String[] args) {
System.out.println(SplitRedPackes(new BigDecimal("100"), 20));
} }
java 红包规则的更多相关文章
- 《Java编程思想第四版》附录 C Java 编程规则
附录 C Java 编程规则 本附录包含了大量有用的建议,帮助大家进行低级程序设计,并提供了代码编写的一般性指导: (1) 类名首字母应该大写.字段.方法以及对象(句柄)的首字母应小写.对于所有标识符 ...
- Day01_05_Java第一个程序 HelloWorld - java类规则
第一个程序Hello World *基础语法规则: 1. 第一个Java程序 HelloWorld! public class HelloWorld{ public static void main( ...
- java命名规则/规范
Java命名规则: 名称只能由字母.数字.下划线.$符号组成. 不能以数字开头,不能包含空格. 名称不能使用Java中的关键字. Java命名规范: 项目名全部小写: project 包名全部 ...
- java 重载规则
首先看Java重载的规则: 1.必须具有不同的参数列表: 2.可以有不同的返回类型,只要参数列表不同就可以: 3.可以有不同的访问修饰符: 4.可以抛出不同的异常: 5.方法能够在一个类中或者在一个子 ...
- Java命名规则总结
1. JAVA源文件的命名 JAVA源文件名必须和源文件中所定义的类的类名相同. 2. Package的命名 Package名的第一部分应是小写ASCII字符,并且是顶级域名之一,通常是com.edu ...
- java命名规则
java变量命名是不能以#开头的.Java变量的命名规则如下:$ .字母.下划线开头都行,不能以数字开头 后面的可以是数字.字母.下划线, 其他的命名方式,都会报错,且不能运行. 以字母.下划线( _ ...
- [JAVA第二课] java命名规则
Java良好的命名规则以及代码风格可以看出来一个程序员的功底,好多公司也会注重这方面,他们招聘员工在有些时候往往就是根据一个人的代码风格来招人,所以下面就就我知道的代码风格作简要的说明一下.Java命 ...
- Java中==规则
普通对象== 一般说来,java中的==指的是比较两个对象的内存地址是否相同.同时,在java中,一旦使用new关键字,则说明在内存中开辟了一段空间,用于存储对象. 假设我们有一个Person类,请看 ...
- Java 命名规则
http://lpacec.iteye.com/blog/25180包名:包名是全小写的名词,中间可以由点分隔开,例如:java.awt.event; 类名:首字母大写,通常由多个单词合成一个类名,要 ...
随机推荐
- hdu6230 Palindrome(manacher+树状数组)
题目链接: Palindrome Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Other ...
- matplotlib 数据可视化
图的基本结构 通常,使用 numpy 组织数据, 使用 matplotlib API 进行数据图像绘制. 一幅数据图基本上包括如下结构: Data: 数据区,包括数据点.描绘形状 Axis: 坐标轴, ...
- linux 系统优化+定时任务
安装软件 通过yum安装 自动补全工具:yum completion yum install -y tree bash-completion wget vim find -[TAB] 更改系统的yum ...
- 【NodeJs】入门笔记一
忙乎了两周,把一个后台模型项目完成了,整个过程又进步不少,私喜一下. 暂时可以悠闲两天,又一次把node教程拿出来,每次都看一点点,积少成多吧. 查了很多资料,觉得从<Node入门>开始看 ...
- my_itoa
#include <iostream> using namespace std; char *my_reverse(char* s) { char *p,*q; p=s;q=s; whil ...
- Centos kvm+ceph
Centos kvm+ceph 一. centos6.5 安装kvm 1. disable selinux 2. 确认支持intel虚拟化 3. 安装需要的包 4.设置桥接网络 5.运行kvm ins ...
- 使用Linq动态排序
Linq排序很方便,如果能动态创建Expression再排序就更方便了. 正序还是倒序排列 var order = typeof(Enumerable).GetMember(direction == ...
- Srping框架中使用@query注解实现复杂查询
[自己项目代码] @Query("select bean from User bean where bean.org.id=?1 and bean.group.id=?2") pu ...
- Yahoo关于性能优化的N条规则
本来这是个老生常谈的问题,上周自成又分享了一些性能优化的建议,我这里再做一个全面的Tips整理,谨作为查阅型的文档,不妥之处,还请指正: 一. Yahoo的规则条例: 谨记:80%-90%的终端响应时 ...
- 数字证书在web应用中实现登陆
1数字证书登录认证的优点 作为企业信息系统的第一道大门,身份认证是确保企业信息资源只能被合法用户所访问的重要保障. 传统的口令认证方式虽然简单,但是由于其易受到窃听.重放等攻击的安全缺陷,使其已无法满 ...