辅助类提供了3个方法:
(1)addWeightNumber(int weight,int num):为某个num赋予weight权重,此权重代表此数字在随机获取时的获得概率;权重大, 则获得的概率就大,权重小,则获得的概率就小。
(2)addWeightNumRange(int weight,int numfrom,int numto,int ... numExcludes);同时为连续多个数字赋予权重,最后这个参数可以排除例外数字,比如addWeightNumRange(5,1,10,5); 表示为1~10(除去5)的数字赋予权重5;
(3)getNextInt();在你赋予权重之后,此方法会随即在你赋予权重的这些数字之中取出一个;
优点:此方法和new Random().nextInt()的优势在于,可以为每个数字赋予权重,并且可以随机取出用户指定的数字集合;
package org.xiazdong.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class IntegerWeightRandom {
private List<Integer> weights = new ArrayList<Integer>();
private List<List<Integer>> numbers = new ArrayList<List<Integer>>();
private Integer totalWeight;
private Random random = new Random();
public IntegerWeightRandom() {
}
private Integer getTotalWeight(){
if(totalWeight == null){
totalWeight = 0;
for(Integer weight:weights){
totalWeight += weight;
}
}
return totalWeight;
}
/*
* 为某个number赋予一个weight,可能一个weight对应多个numbers,因此List<Integer>weight中一个元素对应List<List<Integer>>numbers中的一个List<Integer>
* */
//此函数表示一个weight对应一个number
public void addWeightNumber(int weight,int num){
weights.add(weight);
List<Integer> list = new ArrayList<Integer>();
list.add(num);
numbers.add(list);
}
//此函数表示一个weight对应多个number
public void addWeightNumRange(int weight,int numFrom,int numTo,int...numExcludes){
weights.add(weight);
List<Integer> list = new ArrayList<Integer>();
for(int i = numFrom;i <= numTo;i++){
boolean exclude = false;
for(int numExclude:numExcludes){
if(i == numExclude){
exclude = true;
}
}
if(!exclude){
list.add(i);
}
}
numbers.add(list);
}
/*
* 举例:
* 如果数字8的weight为1,数字9的weight为2,则totalWeight=3,8的范围为(0,1],9的范围为[2,3]如果随机数为2,则在9的范围内
* */
//此函数为随机取一个整数(按照权重概率取)
public Integer getNextInt(){
int weightRandom = random.nextInt(getTotalWeight());
int weightCount = 0;
for(int i = 0;i < weights.size();i++){
int weight = weights.get(i);
if(weightRandom >= weightCount && weightRandom < weightCount + weight){
List<Integer> numList = numbers.get(i);
if(numList.size() == 1){
return numList.get(0);
}
int numRandom = random.nextInt(numList.size());
return numList.get(numRandom);
}
weightCount += weight;
}
return null;
}
}
测试类:
package test.org.xiazdong.util;
import org.junit.Test;
import org.xiazdong.util.IntegerWeightRandom;
public class IntegerWeightRandomTest {
@Test
public void testGetNextInt(){
IntegerWeightRandom random = new IntegerWeightRandom();
random.addWeightNumber(1, 0);
random.addWeightNumber(5, 1);
random.addWeightNumber(9, 2);
random.addWeightNumber(15, 3);
random.addWeightNumber(20, 4);
random.addWeightNumber(30, 5);
random.addWeightNumber(40, 7);
random.addWeightNumber(50, 6);
random.addWeightNumber(60, 8);
random.addWeightNumber(70, 9);
for(int i=0;i<10;i++){
System.out.println(random.getNextInt());
}
}
}