Java 中实现随机无重复数字的方法

时间:2022-07-06 15:57:37 

一般有点开发经验的朋友都能实现这样的功能,只不过是效率上的问题。我们一般在面对这样的问题时,总会平铺直序的联想到,先生成一个数组,然后在一个循环中向数组中添加随机数字,在添加数字的过程中先查找一下数组中是否存在这个数字,如果不存在这个数字就直接添加到数组中;如果存在这个数字就不添 加。我们一般都是这样考虑问题的,这样考虑也能实现功能,我刚才也说了,只不过是效率上的问题。

为了更好地理解这个题意,我们先来看下具体内容:生成一个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");
           }
       }
   }
}

标签:随机,数字
0
投稿

猜你喜欢

  • SpringBoot工程搭建打包、启动jar包和war包的教程图文详解

    2022-05-04 22:09:10
  • C#如何防止程序多次运行的技巧

    2022-11-10 01:18:59
  • Java深入了解数据结构中常见的排序算法

    2021-11-02 23:33:53
  • RocketMQ broker 消息投递流程处理PULL_MESSAGE请求解析

    2021-11-18 17:12:49
  • C++中const的实现细节介绍(C,C#同理)

    2022-10-21 19:43:12
  • C#中深拷贝和浅拷贝的介绍与用法

    2022-11-04 07:42:46
  • 详解Android Activity的启动流程

    2023-07-29 08:06:19
  • java 动态生成bean的案例

    2023-08-09 02:20:05
  • java使用IO流对数组排序实例讲解

    2023-09-04 02:24:19
  • SpringBoot JSON全局日期格式转换器实现方式

    2021-10-03 10:07:28
  • Android使用GestureOverlayView控件实现手势识别

    2023-03-02 08:46:26
  • SpringBoot自定义加载yml实现方式,附源码解读

    2022-01-22 22:39:40
  • Java实现的基于socket通信的实例代码

    2021-12-30 19:06:50
  • C#异步的世界(上)

    2021-09-21 06:01:43
  • Java Swing编写一个简单的计算器软件

    2023-08-12 06:24:04
  • 解析Nacos的API居然存在这么严重的漏洞

    2022-05-29 08:17:52
  • 基于Hibernate中配置文件的学习(分享)

    2022-02-11 12:03:31
  • Java 获取两个List的交集和差集,以及应用场景操作

    2021-11-21 17:49:43
  • Java监听器的作用及用法代码示例

    2023-06-24 06:59:07
  • java高并发锁的3种实现示例代码

    2022-05-23 16:45:47
  • asp之家 软件编程 m.aspxhome.com