1、以及JDK 7 新引入的java.util.concurrent.ThreadLocalRandom**。
特点比较:
- Random虽然是线程安全的,效率比降低。(用了很多CAS的类)ThreadLocalRandom根本没有用到。
- Random产生的随机数可能被预测
- 使用TheadLocalRandom代替Math.random()可以减少竞争,从而获得更好的性能。
工具类:
public class RandomUtil {
private RandomUtil() {}
/**
* 取值范围:[0,max)
* @param max
* @return [0,max)
*/
public static int random(int max) {
return ThreadLocalRandom.current().nextInt(max);
}
/**
* 取值范围:[min,max]
* @param min
* @param max
* @return [min,max]
*/
public static int random(int min, int max) {
if (max - min <= 0) {
return min;
}
return min + ThreadLocalRandom.current().nextInt(max - min + 1);
}
/**
* 取值范围:[min,max]
* @param min
* @param max
* @return [min,max]
*/
public static long random(long min, long max) {
if (max - min <= 0) {
return min;
}
return min + ThreadLocalRandom.current().nextLong(max - min + 1);
}
/**
* 取值范围:[0,max)
* @param max
* @return [0,max)
*/
public static long random(long max) {
return ThreadLocalRandom.current().nextLong(max);
}
/**
* 计算可能性 example:55%的概率,RandomUtils.probable(55,100)
* @param probablility 可能系数
* @param gailv 概率数
* @return
*/
public static boolean probable(int probablility, int gailv) {
return probablility > ThreadLocalRandom.current().nextInt(gailv);
}
/**
* 从list中随机指定数目的元素
* @param list 随机的list
* @param num 随机的数目
* @return
*/
public static <T> List<T> randomList(List<T> list, int num) {
if (list == null) {
throw new IllegalArgumentException("随机list 不能为null");
}
if (list.size() == 0 || num <= 0) {
return new ArrayList<>();
}
// 数目不能大于list的大小
num = num > list.size() ? list.size() : num;
Map<Integer, T> res = new HashMap<>();
for (;;) {
int index = random(list.size());
if (res.containsKey(index)) {
continue;
}
res.put(index, list.get(index));
if (res.size() == num) {
break;
}
}
return new ArrayList<>(res.values());
}
/**
* 从list随机出一个元素
* @param list
* @return
*/
public static <T> T randomList(List<T> list) {
return randomList(list, 1).get(0);
}
/**
* 随机选取数组元素
* @param array
* @param num
* @return
*/
public static <T> List<T> randomArray(T[] array, int num) {
if (array == null) {
throw new IllegalArgumentException("随机array 不能为null");
}
return randomList(Arrays.asList(array), num);
}
/**
* 随机boolean
* @return
*/
public static boolean randomBoolean() {
return ThreadLocalRandom.current().nextBoolean();
}
/**
* 比例随机权重
* @param list
* @return list.index:
* */
public static int randomWeight(List<Integer> list){//30 60 40
DecimalFormat df = new DecimalFormat("######0"); //四舍五入转换成整数
int indexSum = 0;
List<Integer> indexList = new ArrayList<>();
for (Integer integer : list) { //累加值
indexSum +=integer;
}
for(Integer integer : list){ //每个值所占百分比
indexList.add(Integer.parseInt(df.format((double)integer/indexSum*100)));
}
int randomIndex = random(0,100);
int min = 0;
int max = 0;
for(int i = 0;i<indexList.size();i++){
max += indexList.get(i);
if(min < randomIndex && randomIndex < max){
return i;
}
min += indexList.get(i);
}
return 0;
}
}