【面试】shuffle函数的实现
一、前言
有位同学面试的时候被问到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函数的实现的更多相关文章
- shuffle() 函数(转)
定义和用法 shuffle() 函数把数组中的元素按随机顺序重新排列. 若成功,则返回 TRUE,否则返回 FALSE. 注释:本函数为数组中的单元赋予新的键名.这将删除原有的键名而不仅是重新排序. ...
- SSE 系列内置函数中的 shuffle 函数
SSE 系列内置函数中的 shuffle 函数 邮箱: quarrying@qq.com 博客: http://www.cnblogs.com/quarryman/ 发布时间: 2017年04月18日 ...
- 【实践】用 js 封装java shuffle函数(打乱数组下标方法)
此方法返回的会是一个全新的数组 所以并不会像java里的shuffle函数一样返回一个引用一样的数组 思路如下: 1.新建一个函数传入需要打乱下标的数组 2.获取数组的长度 3.新建一个用来保存并且返 ...
- python3中shuffle函数
1. shuffle函数与其他函数不一样的地方 shuffle函数没有返回值!shuffle函数没有返回值!shuffle函数没有返回值!仅仅是实现了对list元素进行随机排序的一种功能 请看下面的坑 ...
- php shuffle()函数 语法
php shuffle()函数 语法 作用:把数组中的元素按随机顺序重新排序:富瑞华 语法:shuffle(array) 参数: 参数 描述 array 必需.规定要使用的数组. 说明:若成功则返回 ...
- SSE系列内置函数中的shuffle函数
SSE 系列内置函数中的 shuffle 函数 邮箱: quarrying@qq.com 博客: http://www.cnblogs.com/quarryman/ 发布时间: 2017年04月18日 ...
- PHP shuffle() 函数
实例 把数组中的元素按随机顺序重新排列: <?php$my_array = array("red","green","blue",&q ...
- 文本数据挖掘---课后作业shuffle函数洗牌C++
题目: 代码如下:#include <iostream> #include <random> #include <algorithm> #include <v ...
- shuffle() 函数
shuffle() 方法将序列的所有元素随机排序. 以下是 shuffle()方法的语法: shuffle (lst ) 注意:此函数是无法直接访问,需要导入 random 模块,然后通过 rando ...
随机推荐
- Unity - 接入Android SDK
在网络上,关于Unity与Android如何进行交互,雨松MOMO大神已经有两篇文章简单介绍了如何操作(1)Unity3D研究院之打开Activity与调用JAVA代码传递参数(2)Unity3D研究 ...
- 拥抱.NET Core,学习.NET Core的基础知识补遗
前言 .NET Core的新特性之一就是跨平台,但由于对之前框架的兼容导致编写一个.NET Core类库变得相当复杂,主要体现为相当多的框架目标和支持平台,今天我们就对.NET Core的跨平台特性进 ...
- 基于Entity Framework 6的框架Nido Framework
随着 Entity Framework 最新主版本 EF6 的推出,Microsoft 对象关系映射 (ORM) 工具达到了新的专业高度,与久负盛名的 .NET ORM 工具相比已不再是门外汉. EF ...
- ENode框架Conference案例分析系列之 - 订单处理减库存的设计
前言 前面的文章,我介绍了Conference案例的业务.上下文划分.领域模型.架构,以及代码整体流程.接下来想针对案例中一些重要的场景,分别做进一步的分析.本文想先介绍一下Conference案例的 ...
- ES7之Decorators实现AOP示例
在上篇博文CoffeeScript实现Python装潢器中,笔者利用CoffeeScript支持的高阶函数,以及方法调用可省略括符的特性,实现了一个类似Python装潢器的日志Demo.这只是一种伪实 ...
- 我的Git手册
本文肯定不是Git的最佳的教程,它只是本人的Git操作手册,我将从一些实际问题出发,让熟悉SVN用户顺利过度到Git来(当然包括我自己了),其中会加入一些个人感受或看法,相信会对大家有些启发.另外,全 ...
- 在C#代码中应用Log4Net(三)Log4Net中配置文件的解释
一个完整的配置文件的例子如下所示,这个是”在C#代码中应用Log4Net(二)”中使用的配置文件. <log4net> <!-- 错误日志类--> <logger nam ...
- 掀起你的盖头来:Unit Of Work-工作单元
写在前面 阅读目录: 概念中的理解 代码中的实现 后记 掀起了你的盖头来,让我看你的眼睛,你的眼睛明又亮呀,好像那水波一模样:掀起了你的盖头来,让我看你的脸儿,看看你的脸儿红又圆呀,好像那苹果到秋天. ...
- 《FaceBook效应》——读后总结
这本书讲述了facebook从如何创建.到风靡全球,并结合facebook的网络效应讲述为什么facebook可以做到社交龙头.读这本书的时候,也可以看看<社交网络>这部电影. faceb ...
- 自定义 checkbox 新玩法 ?
自定义 checkbox 新玩法 ? 第一步:selector 编写 drawable/selector_checkbox_voice.xml <?xml version="1.0&q ...