在工作中发现有很多有序算法,较少见到一些可用的无序随机算法。无序随机算法的目的是让客户感觉每次都不一样,因为一直看一样的会审美疲劳哈。

在jdk自带一种CollectionUtils.shuffle<List<?> list> 使用默认随机源对指定列表进行置换,方便快捷。熟读JDK是如此的重要。

一下两种算法适用于一些特殊场合

特意写了两种算法。一种是利用set集合的特性,加上优化,因为如果list的个数不大,要在list中取的个数比较多的情况下,采用逆向生成算法,最佳适用于大数据量选取少量随机元素。

另外一种是随机置换位置法,每一个位置都有一次换位的机会,最佳适用于小数据量选取大量随机元素。

有好的意见可以分享给我哈。

package com.duotin.japi.common.utils;

import com.duotin.util.CollectionUtils;
import org.apache.commons.lang.math.RandomUtils; import java.util.*; /**
* 生成随机集合工具类
*
*/
public class RandomDataUtil {
public final static int TWO=2;
/**
* 生成随机集合(不重复)
* <p>
* 使用Set的值唯一的特性。
* 最佳适用场合:集合中数目多,取相对较少对象时。在取对象相对较多时(超过集合的一半时)采用逆向方法,
* 在取得对象个数是集合总数的1/2左右时是效率最慢的。
* </p>
* @param list
* @param generateNum 生成集合中元素的个数
* @param <T>
* @return
*/
public <T> List<T> generateRandomDataNoRepeat(List<T> list,Integer generateNum){
List<T> tList = new ArrayList<T>();
if(CollectionUtils.isNotEmpty(list)) {
for (Integer num : generateRandomNoRepeat(list.size(), generateNum)) {
tList.add(list.get(num));
}
}
return tList;
} /**
* 生成随机集合,随机置换位置、随机截取位置法。
* <p>
* 随机置换法:将集合的每个位置值与随机位置的值调换,并随机截取位置.
* 最佳适合场合:集合的数量相对较少,获取较多的随机个数集合。
* </p>
* @param list
* @param generateNum
* @param <T>
* @return
*/
public <T> List<T> generateRandomPermutation(List<T> list,Integer generateNum){
if(CollectionUtils.isNotEmpty(list)) {
checkParams(list.size(),generateNum);
List<T> randomAllList = randomPermutation(list, generateNum);
int initPosition=interceptPosition(list.size(),generateNum);
return randomAllList.subList(initPosition,initPosition+generateNum);
}
return Collections.emptyList();
} /**
* 随机置换算法
* @param list
* @param generateNum
* @param <T>
* @return
*/
private <T> List<T> randomPermutation(List<T> list,Integer generateNum){
for (int i = 0; i < list.size(); i++) {
Integer random=RandomUtils.nextInt(list.size());
T t = list.get(random);
list.set(random,list.get(i));
list.set(i,t);
}
return list;
} /**
* 随机生成截取位置
* @param totalCount
* @param generateNum
* @return
*/
private Integer interceptPosition(Integer totalCount,Integer generateNum){
int num=RandomUtils.nextInt(totalCount);
if(num+generateNum>totalCount){
num=num-generateNum;
}
return num;
}
/**
* 生成不重复的随机数
* @param totalCount
* @param generateNum
* @param
* @return
*/
public Set<Integer> generateRandomNoRepeat(Integer totalCount,Integer generateNum){
if(isLessThanHalfTotalCount(totalCount,generateNum)){
return getRandomNoRepeat(totalCount,generateNum);
}
return getReverseRandomNoRepeat(totalCount,generateNum);
} /**
* 验证参数是否合法
* @param totalCount
* @param generateNum
*/
private void checkParams(Integer totalCount,Integer generateNum){
if(totalCount<generateNum){
throw new IllegalArgumentException("generateNum is out of totalCount");
}
} /**
* 判断使用哪种生成机制
* @param totalCount
* @param generateNum
* @return
*/
private Boolean isLessThanHalfTotalCount(Integer totalCount,Integer generateNum){
if(generateNum<totalCount/TWO){
return Boolean.TRUE;
}
return Boolean.FALSE;
} /**
* 生成set,不重复
* @param totalCount
* @param generateNum
* @return
*/
private Set<Integer> getRandomNoRepeat(Integer totalCount,Integer generateNum){
Set<Integer> set = new HashSet<Integer>();
while (true) {
set.add(RandomUtils.nextInt(totalCount));
if(set.size() == generateNum){
return set;
}
}
} /**
* 逆向生成set,不重复
* @param totalCount
* @param generateNum
* @return
*/
private Set<Integer> getReverseRandomNoRepeat(Integer totalCount,Integer generateNum){
Set<Integer> set = new HashSet<Integer>();
while (true) {
set.add(RandomUtils.nextInt(totalCount));
if(set.size() == totalCount-generateNum){
Set<Integer> setALL=getSetALL(totalCount);
setALL.removeAll(set);
return setALL;
}
}
} /**
* 生成Set
* @param totalCount
* @return
*/
private Set<Integer> getSetALL(Integer totalCount){
Set<Integer> set = new HashSet<Integer>();
for(int i=0;i<totalCount;i++){
set.add(i);
}
return set;
} }

从list中取N个随机生成一个集合的更多相关文章

  1. PYTHON练习题 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数。

    Python 练习 标签: Python Python练习题 Python知识点 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数,如果大于预设的 ...

  2. 转:在0~N(不包括N)范围内随机生成一个长度为M(M <= N)且内容不重复的数组

    1. 最朴素暴力的做法. void cal1() { , j = , num = ; int result[M]; result[] = rand() % N; //第一个肯定不重复, 直接加进去 ; ...

  3. JAVA代码:生成一个集合,自定义大小,100以内的随机整数

    JAVA代码:生成一个集合,自定义大小,100以内的随机整数 方法一:(Random类) package com.dawa.test; import java.util.ArrayList; impo ...

  4. (爬虫)随机生成一个header

    #!/usr/bin/env python #-*- coding: utf-8 -*- #__Author__: yunrui #__Version__: 1.0 #__Time__: 2019/1 ...

  5. python接口自动化中,注册接口随机生成手机号码

    如大家所知在注册接口中,手机号参数需要的是未注册的手机号,而在测试用例中,你写入的手机号不一定是未注册的.所以这时需要对注册接口中传入的手机号做处理.下面我就分享一个课程里面学到的一个处理手机号的py ...

  6. js随机生成一个数组中的随机字符串以及更新验证码

    随机生成m,n范围的值得公式: Math.random()*(n-m)+m: 改正公式:Math.random()*(n+1-m)+m // 生成随机字符串function randomMixed(n ...

  7. 随机获取一个集合(List, Set)中的元素,随机获取一个Map中的key或value

    利用Java提供的Random类.从List或Set中随机取出一个元素,从Map中随机获取一个key或value. 因为Set没有提供get(int index)方法,仅仅能先获取一个随机数后.利用一 ...

  8. 随机获取一个集合(List, Set,Map)中的元素<转>

    import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; impo ...

  9. JS中取整以及随机颜色问题

    前言:感觉自己已经好久好久没有写博客了,最近都是在写在线笔记比较多.现在来到新公司了,昨天刚刚完成一个项目所以今天有空研究研究一下前端方面的技术.下午在看一个游戏代码的时候,发现了几个别人留下的不错的 ...

随机推荐

  1. zookeeper 安装及集群

    一.zookeeper介绍 zookeeper是一个中间件,为分布式系统提供协调服务,可以为大数据服务,也可以为java服务. 分布式系统,很多计算机组成一个整体,作为一个整体一致对外并处理同一请求, ...

  2. springboot + shiro+登录 微信登录 次数验证资料

    分享一个朋友的人工智能教程.零基础!通俗易懂!风趣幽默!大家可以看看是否对自己有帮助,点击查看教程. 1.https://blog.csdn.net/xtiawxf/article/details/5 ...

  3. ACM&OI 基础数论算法专题

    ACM&OI 基础数学算法专题 一.数论基础 质数及其判法 (已完结) 质数的两种筛法 (已完结) 算数基本定理与质因数分解 (已完结) 约数与整除 (已完结) 整除分块 (已完结) 最大公约 ...

  4. 18 12 28 css 浮动 定位

    浮动 浮动特性 1.浮动元素有左浮动(float:left)和右浮动(float:right)两种 2.浮动的元素会向左或向右浮动,碰到父元素边界.其他元素才停下来 3.相邻浮动的块元素可以并在一行, ...

  5. {转}Java 字符串分割三种方法

    http://www.chenwg.com/java/java-%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%88%86%E5%89%B2%E4%B8%89%E7%A7%8D%E6%9 ...

  6. 2.Git基本配置

    用户名和邮箱地址是本地git客户端的一个变量 . 用户每次提交代码都会记录用户名和邮箱 . 设置git的用户和邮箱git config [--local | --global | --system] ...

  7. AXURE方便的功能

    (1)建立一个公共的页面,可以把一些常用的组建放进去,就和代码要封装方法一样,这样省区了用到一次画一次的麻烦. 其中可以包括:弹出框.图标.搜索框之类的. 当然还可以把经常用到的 登陆.注册.忘记密码 ...

  8. GUI(Graphical User Interface)

    译:用户和图形界面 GUI与程序交互的不同方式,包含3基本要素:输入,处理和输出. 常用GUI框架包括以下几种: wxPython Kivy Flexx PyQt Tkinter Pywin32 Py ...

  9. Qt5学习笔记(1)-环境配置(win+64bit+VS2013)

    Qt5学习笔记(1)-环境配置 工欲善其事必先-不装-所以装软件 久不露面,赶紧打下酱油. 下载 地址:http://download.qt.io/ 这个小网页就可以下载到跟Qt有关的几乎所有大部分东 ...

  10. CentOS7设置阿里镜像教程

    阿里镜像官方地址http://mirrors.aliyun.com/ 1.点击官方提供的相应系统的帮助 :2.查看不同版本的系统操作: 为linux系统下载源设置阿里镜像的步骤 : 1. 备份 备份C ...