Collections.shuffle
1.Collections.shuffler
最近有个需求是生成十万级至百万级的所有随机数,最简单的思路是一个个生成,生成新的时候排重,但是这样时间复杂度是o(n^2),网上看了几个博客的解决方法都不是很理想
因为是要求生成所有随机数,可以换个思路,即生成顺序数,然后打乱即可。最后用到了shuffler方法,效率很高,百万级的数据毫秒就能打乱完, 其实这个算法也可以用于生成范围内一定量的随机数。
先介绍下源码实现吧,其实思路很简单。
jdk:
shuffle
public static void shuffle(List<?> list)使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。
前面描述中使用了不确定的词“大致”,因为随机源只是大致上独立选择位的无偏源。如果它是一个随机选择位的最佳源,那么算法将完全一致的选择置换。
此实现向后遍历列表,从最后一个元素一直到第二个元素,将随机选择的元素重复交换到“当前位置”。元素是从列表的一部分随机选择的,该部分列表从第一个元素一直到当前位置(包括)。
此方法以线性时间运行。如果指定列表没有实现 RandomAccess 接口并且是一个大型列表,则此实现在改组列表前将指定列表转储到数组中,并将改组后的数组转储回列表中。这避免了二次行为,该行为是原地改组一个“有序访问”列表引起的。
参数:
list - 要改组的列表。
抛出:
UnsupportedOperationException - 如果指定列表或其列表迭代器不支持 set 操作。
shuffle
public static void shuffle(List<?> list,
Random rnd)使用指定的随机源对指定列表进行置换。所有置换发生的可能性都是相等的,假定随机源是公平的。
此实现向后遍历列表,从最后一个元素一直到第二个元素,将随机选择的元素重复交换到“当前位置”。元素是从列表的一部分随机选择的,该部分列表从第一个元素一直到当前位置(包括)。
此方法以线性时间运行。如果指定列表没有实现 RandomAccess 接口并且是一个大型列表,则此实现在改组列表前将指定列表转储到一个数组中,并将改组后的数组转储回列表中。这避免了二次行为,该行为是原地改组一个“有序访问”列表引起的。
参数:
list - 要改组的列表。
rnd - 用来改组列表的随机源。
抛出:
UnsupportedOperationException - 如果指定列表或其列表迭代器不支持 set 操作。
重载函数的思路是一样的, 如果没有穿随机类就生成一个调第二个函数。
java.util.Collections
public static void shuffle(List<?> list) {
if (r == null) {
r = new Random();
}
shuffle(list, r);
}
private static Random r;
public static void shuffle(List<?> list, Random rnd) {
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i=size; i>1; i--)
swap(list, i-1, rnd.nextInt(i));
} else {
Object arr[] = list.toArray();
// Shuffle array
for (int i=size; i>1; i--)
swap(arr, i-1, rnd.nextInt(i));
// Dump array back into list
ListIterator it = list.listIterator();
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr[i]);
}
}
}
核心就是遍历,首先获取集合的元素个数,如果小于5个或者实现了RandomAccess接口,就循环一遍,随机交换集合中两个相邻的元素的位置,RandomAccess是一个标记接口,如果实现了这个接口就表示支持快速的随机访问操作,类似于数组。
如果大于等于5个元素也没有实现RandomAccess接口,那么就转为数组,之后也是循环,随机交换集合中两个相邻的元素的位置,最后再将数组放回原来的list中。
Collections.shuffle的更多相关文章
- JAVA Collections.shuffle打乱列表
在JAVA中如果想打乱LIST的顺序可以调用Collections.shuffle()或者Collections.shuffle(List<?> list, Random rnd)方法. ...
- Collections.shuffle()源码分析
Java.util.Collections类下有一个静态的shuffle()方法,如下: 1)static void shuffle(List<?> list) 使用默认随机源对列表进行 ...
- 升序 Collections.sort(list) 降序 Collections.reserve(list) 随机 Collections.shuffle(list)
package Day28ketangzuoye; import java.util.ArrayList; import java.util.Collections; import java.util ...
- Collections.shuffle源码阅读
java.util.Collections /** * Randomly permutes the specified list using a default source of * randomn ...
- Collections -集合排序compareTo方法重写,shuffle,addall
package cn.learn.collection.Collections; /* 排序的对象的类,实现comparable借口,重写compareto方法 若要打印必须重写toString方法, ...
- 可变参数和Collections集合工具类的方法_addAll&shuffle
可变参数 可变参数:是JDK1.5之后出现的新特性 使用前提:当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数 使用格式:定义方法时使用 ~修饰符 返回值类型 方法名(数据类 ...
- Java基础Map接口+Collections工具类
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- Java基础Map接口+Collections
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- java Collection.shuffle()随机打乱一个顺序数组
如何打乱一个顺序的数组,其实集合的帮助类Collection就有现成的方法可用,而且效率还蛮高的,总比自定义随机数等等方法要好很多.其实乱序就这么简单,步骤如下: 1. 将一个顺序排列的数组添加到集合 ...
随机推荐
- 搭建自己的Nuget服务器
序言 你们公司有没有好多项目,有没有好多类库,你们的类库是在tfs中管理,还是svn或者github,又或者是各自为政版本类库随意使用? 那么你们使用者写类库的时候方便吗? 有没有更新下载,版本不一致 ...
- CSS 定位之绝对与相对
static,relative,absolute,fixed含义 static(静态定位):元素框正常生成.块级元素生成一个矩形框,作为文档流的 的一部分,行内元素则会常见一个或多个行框,至于其父元素 ...
- 从零开始编写自己的C#框架(11)——创建解决方案
这段时间一直在充电,拜读了园子中大神们的博文(wayfarer的<设计之道>.TerryLee的<.NET设计模式系列文章>.卡奴达摩的<设计模式>还有其他一些零散 ...
- C语言之链表list
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h& ...
- 通过Http接口及SolrNet 两种方法基于Solr5.5.1 实现CURD
前言 老规矩,任何技术的入门我通常都会总结增删改查,本文我就通过HttpWebRequest和SolrNet的方式实现Solr最基础的增删改查(CURD).对于自己的完整项目,同时不想过于依赖第三方类 ...
- Scala集合和Java集合对应转换关系
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 用Scala编码的时候,经常会遇到scala集合和Java集合互相转换的case,特意mark一 ...
- 模仿东京首页banner轮播,京东新闻上下滚动动画实现(动画实现)
接着上篇 微信小程序-阅读小程序demo写:http://www.cnblogs.com/muyixiaoguang/p/5917986.html 首页banner动画实现 京东新闻上下动画实现 想着 ...
- VNC软件的安装及使用方法说明
本篇仅为作业... 实验课程:Linux系统 指导老师:刘臣奇 实验机器:联想y410p 实验时间:2016年9月11日 学生学号:140815 姓名:杨文乾 在一台机器安装viewer的同时,在另一 ...
- JavaWeb_day03_员工信息添加修改删除
day03员工的添加,修改,删除 修改功能 思路 : 点击修改员工数据之后,跳转到单行文本,查询要修改的员工id的全部信息,主键id设置为readonly,其余的都可以修改, 修改之后,提交按钮,提交 ...
- Servlet3.0的可插拔功能
如果说 3.0 版本新增的注解支持是为了简化 Servlet/ 过滤器 / 监听器的声明,从而使得 web.xml 变为可选配置, 那么新增的可插性 (pluggability) 支持则将 Servl ...