Java 中实现随机无重复数字的方法
一般有点开发经验的朋友都能实现这样的功能,只不过是效率上的问题。我们一般在面对这样的问题时,总会平铺直序的联想到,先生成一个数组,然后在一个循环中向数组中添加随机数字,在添加数字的过程中先查找一下数组中是否存在这个数字,如果不存在这个数字就直接添加到数组中;如果存在这个数字就不添 加。我们一般都是这样考虑问题的,这样考虑也能实现功能,我刚才也说了,只不过是效率上的问题。
为了更好地理解这个题意,我们先来看下具体内容:生成一个1-100 的随机数组,但数组中的数字不能重复,即位置是随机的,但数组元素不能重复。在这里,没有给我们规定数组的长度,我们可以让它是1-100之间的任意长度。
接下来让我们看一下如何更好地实现它,通常我们会使用 arraylist 来实现,如下面代码所示:
package cn.sunzn.randomnumber;
import java.util.arraylist;
import java.util.random;
public class demo {
public static void main(string[] args) {
object[] values = new object[20];
random random = new random();
arraylist<integer> list = new arraylist<integer>();
for (int i = 0; i < values.length; i++) {
int number = random.nextint(100) + 1;
if (!list.contains(number)) {
list.add(number);
}
}
values = list.toarray();
/********** 遍历数组并打印数据 **********/
for (int i = 0; i < values.length; i++) {
system.out.print(values[i] + "\t");
if ((i + 1) % 10 == 0) {
system.out.println("\n");
}
}
}
}
上面这个实现过程效率比较低的。因为在每次添加时都要去遍历一下当前列表中是否存在这个数字,时间复杂度是 o(n^2)。我们可以这样思考一下:既然涉及到无重复,我们可以想一下 hashset 和 hashmap 的功能。hashset 实现 set 接口,set 在数学上的定义就是无重复,无次序的集合。而 hashmap 实现 map,也是不允许重复的 key。这样我们可以使用 hashmap 或 hashset 来实现。
在使用 hashmap 实现时,只需要将它的 key 转化成数组就可以了,代码如下:
package cn.sunzn.randomnumber;
import java.util.hashmap;
import java.util.random;
public class demo {
public static void main(string[] args) {
object[] values = new object[20];
random random = new random();
hashmap<object, object> hashmap = new hashmap<object, object>();
/******* 生成随机数字并存入 hashmap *******/
for (int i = 0; i < values.length; i++) {
int number = random.nextint(100) + 1;
hashmap.put(number, i);
}
/********** 从 hashmap 导入数组 **********/
values = hashmap.keyset().toarray();
/*********** 遍历数组并打印数据 ***********/
for (int i = 0; i < values.length; i++) {
system.out.print(values[i] + "\t");
if ((i + 1) % 10 == 0) {
system.out.println("\n");
}
}
}
}
由于 hashset 和 hashmap 的关系太近了,hashset 在底层就是用 hashmap 来实现的,只不过没有 value 的集合,只有一个 key 的集合,所以也可使用 hashset 来实现,代码如下:
package cn.sunzn.randomnumber;
import java.util.hashset;
import java.util.random;
public class demo {
public static void main(string[] args) {
random random = new random();
object[] values = new object[20];
hashset<integer> hashset = new hashset<integer>();
/******* 生成随机数字并存入 hashset *******/
for (int i = 0; i < values.length; i++) {
int number = random.nextint(100) + 1;
hashset.add(number);
}
values = hashset.toarray();
/*********** 遍历数组并打印数据 **********/
for (int i = 0; i < values.length; i++) {
system.out.print(values[i] + "\t");
if ((i + 1) % 10 == 0) {
system.out.println("\n");
}
}
}
}
这样实现效率稍微好些。如果给我们限定了数组的长度,只需要变换下 for 循环,设置成 whlie 循环就可以了。如下所示:
package cn.sunzn.randomnumber;
import java.util.hashset;
import java.util.random;
public class demo {
public static void main(string[] args) {
random random = new random();
object[] values = new object[20];
hashset<integer> hashset = new hashset<integer>();
/****** 生成随机数字并存入 hashset ******/
while (hashset.size() < values.length) {
hashset.add(random.nextint(100) + 1);
}
values = hashset.toarray();
/********** 遍历数组并打印数据 **********/
for (int i = 0; i < values.length; i++) {
system.out.print(values[i] + "\t");
if ((i + 1) % 10 == 0) {
system.out.println("\n");
}
}
}
}