一、前言

  有位同学面试的时候被问到shuffle函数的实现,他之后问我,我知道这个函数怎么用,知道是对数组(或集合)中的元素按随机顺序重新排列。但是没有深入研究这个是怎么实现的。现在直接进入JDK源码进行分析。

二、源码分析

  shuffle函数的源码如下  

    public static void shuffle(List<?> list, Random rnd) {
// 集合大小
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { // 小于shuffle阈值或者可以随机访问(如ArrayList,访问效率很高)
// 从后往前遍历
for (int i=size; i>1; i--)
// 交换指定位置的两个元素
swap(list, i-1, rnd.nextInt(i));
} else { // 如果大于阈值并且不支持随机访问,那么需要先转化为数组,再进行处理
Object arr[] = list.toArray(); // 该数组只是中间存储过程
// 从后往前遍历
for (int i=size; i>1; i--)
// 交换指定位置的两个元素
swap(arr, i-1, rnd.nextInt(i));
// 重新设置list的值
ListIterator it = list.listIterator();
// 遍历List
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr[i]);
}
}
}

  说明:从源码可知,进行shuffle时候,是分成两种情况。

  1. 若集合元素个数小于shuffle阈值或者集合支持随机访问,那么从后往前遍历集合,交换元素。

  2. 否则,先将集合转化为数组(提高访问效率),再进行遍历,交换元素(在数组中进行),最后设置集合元素。

  其中涉及的swap函数如下,两个重载函数

    public static void swap(List<?> list, int i, int j) {
// 交换指定位置的两个元素
final List l = list;
l.set(i, l.set(j, l.get(i)));
} private static void swap(Object[] arr, int i, int j) {
Object tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}

  说明:两个重载函数很简单,不再累赘。

三、总结

  多看源码,源码也是最直观的。平时多注意积累,水滴石穿。谢谢各位园友的观看~

【面试】shuffle函数的实现的更多相关文章

  1. shuffle() 函数(转)

    定义和用法 shuffle() 函数把数组中的元素按随机顺序重新排列. 若成功,则返回 TRUE,否则返回 FALSE. 注释:本函数为数组中的单元赋予新的键名.这将删除原有的键名而不仅是重新排序. ...

  2. SSE 系列内置函数中的 shuffle 函数

    SSE 系列内置函数中的 shuffle 函数 邮箱: quarrying@qq.com 博客: http://www.cnblogs.com/quarryman/ 发布时间: 2017年04月18日 ...

  3. 【实践】用 js 封装java shuffle函数(打乱数组下标方法)

    此方法返回的会是一个全新的数组 所以并不会像java里的shuffle函数一样返回一个引用一样的数组 思路如下: 1.新建一个函数传入需要打乱下标的数组 2.获取数组的长度 3.新建一个用来保存并且返 ...

  4. python3中shuffle函数

    1. shuffle函数与其他函数不一样的地方 shuffle函数没有返回值!shuffle函数没有返回值!shuffle函数没有返回值!仅仅是实现了对list元素进行随机排序的一种功能 请看下面的坑 ...

  5. php shuffle()函数 语法

    php shuffle()函数 语法 作用:把数组中的元素按随机顺序重新排序:富瑞华 语法:shuffle(array) 参数: 参数 描述 array 必需.规定要使用的数组. 说明:若成功则返回 ...

  6. SSE系列内置函数中的shuffle函数

    SSE 系列内置函数中的 shuffle 函数 邮箱: quarrying@qq.com 博客: http://www.cnblogs.com/quarryman/ 发布时间: 2017年04月18日 ...

  7. PHP shuffle() 函数

    实例 把数组中的元素按随机顺序重新排列: <?php$my_array = array("red","green","blue",&q ...

  8. 文本数据挖掘---课后作业shuffle函数洗牌C++

    题目: 代码如下:#include <iostream> #include <random> #include <algorithm> #include <v ...

  9. shuffle() 函数

    shuffle() 方法将序列的所有元素随机排序. 以下是 shuffle()方法的语法: shuffle (lst ) 注意:此函数是无法直接访问,需要导入 random 模块,然后通过 rando ...

随机推荐

  1. OPENDATASOURCE读取远程数据库数据中文乱码问题-sqlserver R2

    insert into kraft_sync_Store(StoreName,StoreCode,Province,PrefectureCity,CountyCity,Region,Area,Unit ...

  2. canvas :曲线的面积图 加渐变效果

    document.body.innerHTML = '<canvas></canvas>' var cvs = document.querySelector("can ...

  3. html 5 实现拖放效果

    在html5中要实现拖放操作,相对于以前通过鼠标操作实现,要简单得多,数据安全性也更有保障.只需要以下几步即可. 给被拖拽元素添加draggable属性,如果是文件拖放. 在拖拽元素的dragstar ...

  4. 系统吞吐量(TPS)、用户并发量、性能测试概念和公式

    分享一个概念: http://www.ha97.com/5095.html

  5. [Window Title] (没有登录) [Content] ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务 [OK]

    重启Oracle服务

  6. windows或mac上对iOS设备截图

    1.需要在设备上安装插件“设置”--“开发者”的选项 2.启动"com.apple.mobile.screenshotr"服务 3.和设备scoket通讯,拿到截图.

  7. 基于 Asp.Net的 Comet 技术解析

    Comet技术原理 来自维基百科:Comet是一种用于web的技术,能使服务器能实时地将更新的信息传送到客户端,而无须客户端发出请求,目前有两种实现方式,长轮询和iframe流. 简单的说是一种基于现 ...

  8. 从“差不多了”到 正式发布 -- 新浪微博WinPhone UWP版诞生记

    本文粗略记述了UWP团队从接手新浪微博项目到发布第一版的过程.本文不是技术贴,而是回顾“软件工程周期失控是一种怎样的体验”. 接手新项目:捡了个大便宜 2016年1月份,UWP team开始接手新浪微 ...

  9. Python黑帽编程2.6 模块

    Python黑帽编程2.6 模块 我们已经学习了如何在你的程序中定义一次函数而重用代码.如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块.模块基本上就是一个 ...

  10. Win8 Metro动态加载内容框架

    制作背景 为了参加ImagineCup 2013 世界公民类比赛,我们设计制作了一个可动态扩展的幼教类App.这个App需要能动态加载内容,内容包括带动画可交互的电子书,动画,视频,游戏. 技术支持 ...