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");
}
}
}
}
猜你喜欢
- 一、效果图 二、RippleDrawable基本概念介绍 (1)、RippleDrawableRippleDrawable可以实
- 1.由于需要删除文件,因此需要如下权限: <uses-permission android:name="android.pe
- 本文实例为大家分享了PropertyDescriptor反射调用set和get方法,供大家参考,具体内容如下第一段:package com.
- Java的SPI机制实例详解SPI的全名为Service Provider Interface.普通开发人员可能不熟悉,因为这个是针对厂商或
- 1.什么是逆向工程mybaits需要程序员自己编写sql语句,mybatis官方提供逆向工程 可以针对单表自动生成mybatis执行所需要的
- 前言在Windows下JAVA用到的环境变量主要有3个,JAVA_HOME、CLASSPATH、PATH,下面来详细的介绍。JAVA_HOM
- 网上android播放器虽然挺多,感觉提供的歌词显示功能比较死板,要么搜索给的条件死死的,要么放置sdcard内部的歌词格式需要统一,应该提
- Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各种属性。建议大家使用S
- 一、java方法重写方法的重写是子类根据需求对父类继承的方法进行重新的编写,在重写时,可以使用super方法的方式来保留父类中的方法,注意:
- 本文实例为大家分享了Handler实现倒计时功能的具体代码,供大家参考,具体内容如下1、需求1.1 实现目标当后台传递一个时间戳时,与当前系
- 一、问题场景使用Logger.error方法时只能打印出异常类型,无法打印出详细的堆栈信息,使得定位问题变得困难和不方便。二、先放出结论Lo
- springboot项目启动的时候参数无效今天启动一个springboot项目发现启动的时候输入的参数都是不能生效,但是yaml文件的配置却
- Bezier曲线的形状是通过一组多边折线(特征多边形)的各顶点唯一地定义出来的。在这组顶点中:(1)只有第一个顶点和最后一个顶点在曲线上;(
- 本文实例讲述了C#检查指定对象是否存在于ArrayList集合中的方法。分享给大家供大家参考。具体分析如下:C#的ArrayList提供了一
- Android—沉浸式状态栏我们的征程是星辰大海,而非人间烟尘去掉标题栏首先去掉对应主题下面的Android自带的ActionBar,只需要
- 气球状提示框的介绍和系统通知变化NotifyIcon控件表示系统右下角任务栏上的托盘图标,其ShowBalloonTip方法用于显示任务栏中
- RenderScript 介绍在开始之前,先看下 RenderScript 的官方介绍:RenderScript is a framewor
- 本文实例为大家分享了java实现KFC点餐系统的具体代码,供大家参考,具体内容如下package KFC点餐系统;//food 类 publ
- 1、堆的定义①、它是完全二叉树,除了树的最后一层节点不需要是满的,其它的每一层从左到右都是满的。注意下面两种情况,第二种最后一层从左到右中间
- 一、前言开发中经常要处理用户一些文字的提交,所以涉及到了敏感词过滤的功能,参考资料中DFA有穷状态机算法的实现,创建有向图。完成了对敏感词、