先创建个奖励对象
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class NewSysBoxInfo {
@ApiModelProperty("奖励Id")
private Integer id;
@ApiModelProperty("权重")
private Integer percentage;
@ApiModelProperty("奖励的上限数量")
private Integer rewardNum;
}
权重测试
@Slf4j
public class 权重测试 {
public static void main(String[] args) {
List<NewSysBoxInfo> list = new ArrayList<>();
list.add(NewSysBoxInfo.builder().id(0).percentage(60).rewardNum(100).build());
list.add(NewSysBoxInfo.builder().id(1).percentage(20).rewardNum(100).build());
list.add(NewSysBoxInfo.builder().id(2).percentage(20).rewardNum(100).build());
list.add(NewSysBoxInfo.builder().id(3).percentage(10).rewardNum(100).build());
if (CollectionUtils.isEmpty(list)){
log.error("奖励列表不可为空");
return;
}
list = list.stream().sorted(Comparator.comparing(NewSysBoxInfo::getPercentage).reversed()).collect(Collectors.toList());
int r1 = 0;
int r2 = 0;
int r3 = 0;
int r4 = 0;
NewSysBoxInfo boxInfo2 = null;
long s = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
boxInfo2 = getPrizeDouble(list);
if (boxInfo2.getId() == 0) {
r1 += 1;
}
if (boxInfo2.getId() == 1) {
r2 += 1;
}
if (boxInfo2.getId() == 2) {
r3 += 1;
}
if (boxInfo2.getId() == 3) {
r4 += 1;
}
}
long e = System.currentTimeMillis();
System.out.println("耗时" + (e - s) + "毫秒");
System.out.println("1号出现:" + r1 + "次");
System.out.println("2号出现:" + r2 + "次");
System.out.println("3号出现:" + r3 + "次");
System.out.println("4号出现:" + r4 + "次");
}
public static NewSysBoxInfo getPrizeDouble(List<NewSysBoxInfo> prizes) {
try {
double sumWeight = prizes.stream().mapToDouble(NewSysBoxInfo::getPercentage).sum();
double randomNumber;
randomNumber = Math.random();
double d1 = 0;
double d2 = 0;
for (NewSysBoxInfo prize : prizes) {
d2 += Double.parseDouble(String.valueOf(prize.getPercentage())) / sumWeight;
if (randomNumber >= d1 && randomNumber <= d2) {
return prize;
}
d1 += Double.parseDouble(String.valueOf(prize.getPercentage())) / sumWeight;
}
} catch (Exception e) {
System.out.println("出错原因:" + e.getMessage());
}
return null;
}
public static NewSysBoxInfo getPrizeInt(List<NewSysBoxInfo> prizes) {
int sumWeight = prizes.stream().mapToInt(NewSysBoxInfo::getPercentage).sum();
int randomNum = new Random().nextInt(sumWeight);
for (NewSysBoxInfo prize : prizes) {
if ((randomNum -= prize.getPercentage()) < 0) {
return prize;
}
}
return null;
}
}