java随机⾦额_java使⽤BigDecimal实现随机⾦额红包拆分算
法
@Service
public class SplitRedPacketsServiceImpl implements SplitRedPacketsService {
//红包最⼤⾦额
private static final BigDecimal MAXMONEY = new BigDecimal("200");
/**
* 红包拆分⽣成list集合
* 1.⽣成count个红包的list,将最⼩⾦额分配到每个红包上
* 2.随机⽣成⼀个数值,在原list上做加法
* @param money 总⾦额
bigdecimal取值范围* @param count 总数
* @param minmoney 最⼩⾦额
* @param maxmoney 最⼤⾦额
* @param bigred ⼤包固定⾦额
* @param bigcount ⼤包个数
* @return
*/
public List splitRedPackets(BigDecimal money, BigDecimal maxmoney, BigDecimal minmoney, BigDecimal count, BigDecimal bigred, BigDecimal bigcount)
{
//计算⼩包⾦额总数和总⾦额
count = count.subtract(bigcount);
money = money.subtract(bigcount.multiply(bigred));
//⼤包固定⾦额集合
List bigList = new ArrayList();
for(int i=0;i
{
bigList.add(bigred);
}
//原始list--⼩包list
List list = new ArrayList();
maxmoney = (maxmoneypareTo(MAXMONEY)==1)?MAXMONEY:maxmoney;
/**
* 1.将最⼩⾦额分配到每个红包上
* 2.减去分配的⼩包⾦额
* 3.剩余总⾦额 =总⾦额-最⼩⾦额*最⼩⾦额数
*/
for(int i=0;i
{
list.add(minmoney);
}
BigDecimal minsum = minmoney.multiply(count);
BigDecimal totalMoney = money.subtract(minsum);
BigDecimal realMaxmoney = maxmoney.subtract(minmoney);
/
/判断是否符合取值区间
if(!isRight(totalMoney,count,realMaxmoney,new BigDecimal("0")))
{
return null;
}
//合并后的新包
List listnew = new ArrayList();
for(int i=0;i
{
BigDecimal one = randomRedPacket(totalMoney,new BigDecimal("0"),realMaxmoney,new BigDecimal(count.intValue()-i)); listnew.(i).add(one));
totalMoney = totalMoney.subtract(one);
}
//合并打包固定⾦额集合
listnew.addAll(bigList);
Collections.shuffle(listnew);
return listnew;
}
/**
* 随机⽅法产⽣⼀个在最⼤值和最⼩值之间的⼀个红包,
* 并判断该红包是否合法,是否在产⽣这个红包之后红包⾦额变成负数。
* 另外,在这次产⽣红包值较⼩时,下⼀次就产⽣⼀个⼤⼀点的红包。
* @param money 总⾦额
* @param mins 最⼩⾦额
* @param maxs 最⼤⾦额
* @param count 红包总数
* @return
*/
private BigDecimal randomRedPacket(BigDecimal money,BigDecimal mins,BigDecimal maxs,BigDecimal count) {
if(count.intValue()==1)
{
return money.setScale(2,BigDecimal.ROUND_UP);
}
if(minspareTo(maxs)==0 )
{
return mins;//如果最⼤值和最⼩值⼀样,就返回mins
}
BigDecimal max = (maxspareTo(money)==1)?money:maxs;
//返回指定范围的随机数,保留两位⼩数
BigDecimal random = BigDecimal.valueOf(Math.random());
BigDecimal middle = maxs.subtract(mins);
BigDecimal middle2 = random.multiply(middle).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal one = middle2.add(mins);
BigDecimal moneyOther = money.subtract(one);
if(isRight(moneyOther,count.subtract(new BigDecimal("1")),maxs,mins))
{
return one;
}
else{
//重新分配
BigDecimal avg = moneyOther.divide(count.subtract(new BigDecimal("1")),2,BigDecimal.ROUND_UP);
if(avgpareTo(mins)==-1)
{
return randomRedPacket(money,mins,one,count);
}else if(avgpareTo(maxs)==1)
{
return randomRedPacket(money,one,maxs,count);
}
}
return one;
}
/**
* 判断是否符合取值区间
* @param money 总⾦额
* @param count 总数
* @return
*/
private boolean isRight(BigDecimal money,BigDecimal count,BigDecimal maxs,BigDecimal mins) {
BigDecimal avg = money.divide(count,2,BigDecimal.ROUND_UP);
if(avgpareTo(mins) ==-1){
return false;
}
else if(avgpareTo(maxs) ==1)
{
return false;
}
return true;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论