import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;
/**
* @author:linxu
* @Date:2020-7-24 00:09:54
*/
public class WeightRandomTemplate {
public static void main(String[] args) {
List<DefaultWeightWrap> rewardWraps = new ArrayList<>();
rewardWraps.add(new RewardWrap(12881, "一等奖", 1, 1, 10));
rewardWraps.add(new RewardWrap(12882, "二等奖", 1, 2, 30));
rewardWraps.add(new RewardWrap(12883, "三等奖", 1, 3, 50));
//默认奖励,如果抽不到奖,默认抽中安慰奖【参与奖】
RewardWrap rewardWrap = new RewardWrap(12884, "安慰奖", 1, 4, 60);
rewardWraps.add(rewardWrap);
WeightRandom<DefaultWeightWrap> weightRandom = new WeightRandom<>(rewardWraps, rewardWrap);
//模拟抽奖二十次【第一种方式调用】
for (int i = 0; i < 20; i++) {
RewardWrap rewardWrapRandom = (RewardWrap) weightRandom.randomWeightWrap();
System.out.println(rewardWrapRandom.toString());
}
//模拟抽奖二十次【第二种方式调用】
for (int i = 0; i < 20; i++) {
RewardWrap rewardWrapRandom = (RewardWrap) weightRandom(new IWeightRandom<DefaultWeightWrap>() {
@Override
public List<DefaultWeightWrap> applyWraps() {
return rewardWraps;
}
@Override
public DefaultWeightWrap applyDefaultWrap() {
return rewardWrap;
}
});
System.out.println(rewardWrapRandom.toString());
}
}
//测试实现类
public static class RewardWrap extends DefaultWeightWrap {
private int rewardId;//奖励id
private String rewardName;//奖励名称
private int rewardValue;//数量
private int rank;//奖励排名1等奖,2等奖
public RewardWrap(int rewardId, String rewardName, int rewardValue, int rank, int weight) {
this.rewardName = rewardName;
this.rewardValue = rewardValue;
this.rewardId = rewardId;
this.rank = rank;
this.weight = weight;
}
public int getRewardId() {
return rewardId;
}
public void setRewardId(int rewardId) {
this.rewardId = rewardId;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
@Override
public String toString() {
return "Reward{" +
"rewardId=" + rewardId +
", rewardName='" + rewardName + '\'' +
", rewardValue=" + rewardValue +
", rank=" + rank +
'}';
}
}
/**
* 方式1【创建对象调用的方式】
*
* @param <T>
*/
public static class WeightRandom<T extends DefaultWeightWrap> {
private List<T> content;//目标集合数据
private T defaultResult;//默认返回值【参与奖励】
public WeightRandom(List<T> content, T defaultResult) {
this.content = content;
this.defaultResult = defaultResult;
}
public T randomWeightWrap() {
int s = content.stream().mapToInt(DefaultWeightWrap::getWeight).sum();
int r = ThreadLocalRandom.current().nextInt(s);
Optional<T> o = content.stream().filter(t -> { int result = r - t.getWeight();return result < 0; }).findFirst();
return o.orElse(defaultResult);
}
}
/**
* 方式2【静态方法,内部实现接口方式的调用】
*
* @param iWeightRandom
* @param <T>
* @return
*/
public static <T extends DefaultWeightWrap> T weightRandom(IWeightRandom<T> iWeightRandom) {
int s = iWeightRandom.applyWraps().stream().mapToInt(DefaultWeightWrap::getWeight).sum();
int r = ThreadLocalRandom.current().nextInt(s);
Optional<T> o = iWeightRandom.applyWraps().stream().filter(t -> { int result = r - t.getWeight();return result < 0; }).findFirst();
return o.orElse(iWeightRandom.applyDefaultWrap());
}
public interface IWeightRandom<T extends WeightRandomTemplate.DefaultWeightWrap> {
List<T> applyWraps();//目标集合数据
T applyDefaultWrap();//默认返回值【参与奖励】
}
//权重包装基类
public static abstract class DefaultWeightWrap {
public int weight;//权重
public int getWeight() {
return weight;
}
@Override
public String toString() {
return "DefaultWeightWrap{" +
"weight=" + weight +
'}';
}
}
}
测试结果:
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12882, rewardName='二等奖', rewardValue=1, rank=2}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12881, rewardName='一等奖', rewardValue=1, rank=1}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12883, rewardName='三等奖', rewardValue=1, rank=3}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12881, rewardName='一等奖', rewardValue=1, rank=1}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12882, rewardName='二等奖', rewardValue=1, rank=2}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12883, rewardName='三等奖', rewardValue=1, rank=3}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12883, rewardName='三等奖', rewardValue=1, rank=3}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Reward{rewardId=12884, rewardName='安慰奖', rewardValue=1, rank=4}
Process finished with exit code 0