List redInfoList = new ArrayList<>();
// 红包有误
if(num < REDPACK_MIN_QUANTITY || num > REDPACK_MAX_QUANTITY)
returnredInfoList;//校验:金额大于0
if(redMoney.compareTo(BigDecimal.ZERO) != 1) {returnredInfoList;
}if(num <= 1) {
redInfoList.add(redMoney);returnredInfoList;
}
Random random= newRandom();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);
}returnredInfoList;
}/*** 拼手气红包
*@paramredMoney 红包金额
*@paramnum 红包数量
*@paramrandom 随机数生成对象
*@paramerrorNum 错误测试
*@return单个红包金额*/
private static BigDecimal fightLuckRedPacked(BigDecimal redMoney, int num, Random random, interrorNum) {if(num <= 1) {returnredMoney;
}if(errorNum >ERROR_MAX_NUM) {//随机金额产生错误次数超过上限,返回最小值
returnSINGLE_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);
}returncurRedMoney;
}public static voidmain(String[] args) {
System.out.println(SplitRedPackes(new BigDecimal("100"), 20));
}
}