话不多说直接上代码,可直接复制代码进行测试


//从数据库查询出每个分类的概率,注意查出来的值累加必须等于100%
ArrayList<BigDecimal> objects = new ArrayList<>();

//方便测试添加
objects.add(BigDecimal.valueOf(0.4));//概率40%
objects.add(BigDecimal.valueOf(0.2));//概率20%
objects.add(BigDecimal.valueOf(0.1));//概率10%
objects.add(BigDecimal.valueOf(0.3));//概率30%

//对结果进行升序
List<BigDecimal> listAsc = objects.stream().sorted().collect(Collectors.toList());
System.out.println(listAsc);

//创建新的集合用来保存类加后的结果
ArrayList<BigDecimal> newList = new ArrayList<>();
//创建一个map来保存累加后的key和value
HashMap<Object, Object> map = new HashMap<>();

//创建局部变量用来接收累加后的概率
BigDecimal t = new BigDecimal(0);
//循环加入newList
for (int i = 0; i < listAsc.size(); i++) {
    BigDecimal bigDecimal = listAsc.get(i);
    t = t.add(bigDecimal);
    newList.add(t);
    map.put(t, listAsc.get(i));
}
//进行0-1之间的随机
BigDecimal random = BigDecimal.valueOf(Math.random());
System.out.println(random);
//局部变量用来接收随机后的概率区间
BigDecimal r = null;
for (BigDecimal value : newList) {
    /*
    由于进行了排序,遍历从最低向高遍历,将value减去随机到的数大于0说明在这个区间
    比如商品概率为0.4,那么40%的区间为0.6-1那么对应的累加后的概率为1,
    假设随机到0.61满足40%区间条件,下面if成立会返回1然后赋值给r。
    注意:value为累加后的值需要从map取出真的概率对应的商品
     */
    if (value.subtract(random).compareTo(BigDecimal.valueOf(0))>0) {
        r =value;
        break;
    }
}
Object o = map.get(r);
System.out.println(o);
//拿到结果处理后续逻辑