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