Javase随机数类、日期类、包装类的基础知识示例详解
作者:J1yyy
一、Random随机数类
1. 基本使用
import java.util.Random; public class RandomDemo { public static void main(String[] args) { Random random = new Random(); // 在int的范围内产生随机数 int a = random.nextInt(); //bound:边界的意思,不包含边界10, 产生[0, 10) 范围内的随机数 int b = random.nextInt(10); // 产生[1, 11) 范围内的随机数,左右边界一起+1 int c = random.nextInt(10) + 1; //要是要产生[6,8]的随机数就是x+6=(8+1),x=3,那就是nextInt(3)+6 //因为左边界一定是0,想要左边界为6就要+6 int c = random.nextInt(3) + 6; } }
2. Random类常用方法及使用场景
方法 | 使用方法及结果 | 实际开发使用场景 |
---|---|---|
nextInt(bound) | 返回[0, bound)范围的随机整数 int num = random.nextInt(100); // 0-99 | 数组随机索引、抽奖系统、验证码生成、游戏中的随机事件、分页数据随机采样 |
nextDouble() | 返回[0.0, 1.0)的随机双精度数 double prob = random.nextDouble(); // 0.0-1.0 | 概率判断(如70%成功率)、随机折扣计算、机器学习中的随机初始化、A/B测试分组 |
nextBoolean() | 返回true或false boolean flag = random.nextBoolean(); // true/false | 随机开关功能、50%概率事件、随机选择是/否、随机启用/禁用特性 |
nextInt() | 返回int范围内的随机整数 int randomNum = random.nextInt(); // -2³¹到2³¹-1 | 生成唯一ID种子、哈希计算、需要大范围随机数时 |
nextLong() | 返回long范围内的随机数 long id = random.nextLong(); // 极大范围随机数 | 生成数据库主键、分布式ID生成、需要更大范围随机数时 |
nextBytes() | 用随机字节填充数组 byte[] bytes = new byte[16]; random.nextBytes(bytes); | 加密算法、生成随机令牌、安全相关的随机数生成 |
nextFloat() | 返回[0.0, 1.0)的随机浮点数 float randFloat = random.nextFloat(); // 0.0-1.0 | 图形处理、游戏物理引擎、需要轻量级浮点随机数时 |
nextGaussian() | 返回高斯分布随机数(均值0,标准差1) double normal = random.nextGaussian(); | 统计学模拟、自然现象建模、金融风险分析、AI训练数据生成 |
最常用的三个方法:
- nextInt(bound) - 使用频率最高,几乎每个需要随机数的场景都会用到
- nextDouble() - 概率相关计算的必备方法
- nextBoolean() - 简单的二选一随机场景非常实用
3. 自定义范围随机数
根据1.基本使用的第四个方法[6,8]的推导得出
我们可以用封装方法获取指定范围内的随机数
public static int getRandomInRange(int min, int max) { Random random = new Random(); //左边界一定是min,且包含min //右边界为max-min+1,如果不+1将会是,[min,max)不包含右边界 return random.nextInt(max - min + 1) + min; } // 调用示例(在main函数里面的代码):获取[6,8]范围内的随机数 int num = getRandomInRange(6, 8);
4. 种子(Seed)的作用
Random类支持设置种子,相同种子会产生相同的随机数序列:
随机出来的数字是固定好的
相同种子 第1次运行 从第一个到最后一个数字和 第n次运行 的第一个到最后的数字都是一一对应相同的
Random random1 = new Random(123); // 固定种子 Random random2 = new Random(123); // 相同种子 // random1和random2将产生相同的随机数序列
计算机生成的是伪随机数,实际上是通过种子值计算出来的序列。
二、日期时间类
1. Date类
Date类是Java中最基础的日期类
(!!!不要和data搞混,data是数据)
import java.util.Date; public class DateDemo { public static void main(String[] args) { Date date = new Date(); // 自动调用toString(), System.out.println(date); //System.out.println(date.toString());但是会在编译器里面发现toString()是灰色的,灰色的就是没必要写。 } }
Date类的toString()方法也被重写了,没重写的话就会打印出一个地址值(也就是object.toString()),重写了会输出可读的日期时间格式(但其实也不是很能看得懂)。
Date类的方法
这些方法可以用来获取时间的某些值,拼接输出自己想要的日期格式,其实就是单纯的字符串拼接。
划斜杠的 就是已经被jdk弃用了,不推荐使用
Date类的方法有很多,但是了解一下就行,有的方法可以用接下来会讲的日历类来转化。
Date类的常用方法
// 获取年份(需要+1900) int year = date.getYear() + 1900; // 获取时间戳(1970年1月1日至今的毫秒数) long timestamp = date.getTime();
- getYear:计算机诞生1970左右,所以计算机把1900当成起始年份,数出来的要再加上1900才是当前年份
- getTime:时间戳,所有编程语言都有的,指的是到1970年一月一号零点零分零秒的毫秒数。
- 验证:除以1000(1000毫秒=1秒),60,60,24,365(单位的换算)再加上1970就是当前的年份,除完是个int类型但是其实还有一些毫秒被略掉了(类似于四舍五入),这些毫秒还可以再接着除拿来算几月几日几点几分几秒。
2. Calendar日历类
Calendar是抽象类,不能直接实例化:
就是没办法new Calendar() 来创建实例,只能借助他的静态工厂方法 Calendar.getInstance() 来获取一个 Calendar 类型的对象,这个对象实际上是它的某个具体子类(如 GregorianCalendar)的实例。
学习时候可以直接把calendar打印出来看看输出什么,一步步理解。
打印出来一大堆乱七八糟但是又能看懂一点点的东西:(翻一下jdk看看每个变量代表啥意思,不然直接字面意思理解也行)
java.util.GregorianCalendar[time=1756092317924,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2025,MONTH=7,WEEK_OF_YEAR=35,WEEK_OF_MONTH=5,DAY_OF_MONTH=25,DAY_OF_YEAR=237,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=4,AM_PM=0,HOUR=11,HOUR_OF_DAY=11,MINUTE=25,SECOND=17,MILLISECOND=924,ZONE_OFFSET=28800000,DST_OFFSET=0]
日历类常用方法
- Gettime():
把日历类对象转化为Date对象
Date times=calendar.getTime(); - Get():有返回值返回int类型,就是获取日历类对象的年、月……等等。
括号里面写calendar.Year,calendar.Month……,里面也可以写数字,但是要点进去看数字代表的是什么意思(对应年、月……),不推荐。 - Set():没有返回值,set(int field, int value)
里面左边写你想设置的年月日(calendar.Year…),右边写你想设置的值,如果你设置3000月,那么多出来的会换算加到年上(除12),日 也一样会换算加到 月/年 上
只是修改了数据,要查看的话还要用.getTime()方法来实例化一个Date对象。 - Add():同set()一样没有返回值
给年月…加上多少,可以传负数,相当于减了
3. SimpleDateFormat日期格式化
格式化日期类:英文名太长记不住键盘连着敲SDF就行
在选择构造器的时候一般选第一个构造器,选择传一个模板pattern
Pattern
使用占位符代替年月日时分秒的数据,占位符的大小写有区分!!
当很多个一样的占位符在一块(如yyyyyyyyyyyy),他会只输出后面的,前面的用000占位(变成000000002025),但是要是(yyyyMMyyyyMMyyyyMM)那他都会输出出来(202508202508202508),因为他碰到了别的数据。
他的底层逻辑其实就是字符串的“替换”,和用date方法输出想要的日期格式一样。
查看jdk文档看看占位符里每个字母代表啥意思
常用的占位符:
- yyyy:4位年份
- MM:2位月份
- dd:2位日期
- HH:24小时制小时
- mm:分钟
- ss:秒
常用的pattern(模板):
SimpleDateFormat常用方法
- Sdf.fomat():有字符串的返回值
按照pattern的格式把传进来的Date变成字符串
括号里面传一个时间,没有就在里面new Date - Sdf. Parse():解析转换,把长得像日期的字符串变成日期Date。
格式一定要和pattern一样不然会报错,编译时会有异常,往上抛就行,parse的作者考虑到你传过来的字符串可能是乱传的所以他要你处理一下,在main后面加上throws parseexception,也可以try catch处理一下只要编译时不报错就行
代码示例
import java.text.SimpleDateFormat; import java.util.Date; public class SDFDemo { public static void main(String[] args) { // 创建格式化模板 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 格式化日期为字符串 String formattedDate = sdf.format(new Date()); System.out.println(formattedDate); // 解析字符串为日期,也可以在main(String[] args)后面加上throws parseexception抛出异常 try { Date date = sdf.parse("2025-08-25 12:00:00"); System.out.println(date); } catch (ParseException e) { e.printStackTrace(); } } }
三、包装类(Wrapper Classes)
1. 基本数据类型与包装类对应关系
总共八个基本数据类型
除了int和char变了,其他的都是改个大小写
基本类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
每个类型默认的数据类型:数字int,浮点double,字符char,布尔boolean
2. 装箱与拆箱
- 装箱: 把基本数据类型转化为包装类
在基本类型和包装类互相对应的时候可以用自动装箱来转化相应类型
// 手动装箱 Integer i1 = Integer.valueOf(100);//工厂方法 Integer i2 = new Integer(100);//构造函数法 // 自动装箱 直接赋值 //自动装箱(autoboxing)会将基本类型 int 转换为 Integer 类型 Integer i3 = 100;
- 拆箱: 把包装类变回基本数据类型
// 手动拆箱 int value = i1.intValue(); // 自动拆箱 int num = i1;//直接把Integer类型的值赋给int类型的num int sum = i1 + i2;//进行运算
3. 小练习
下列五个分别输出什么?有点难度
小提示:
基本数据类型和包装类“= =”比较的是值
两个包装类对象之间的 “= =”比较的是地址
答案:TFFTT
解析:
true:包装类(i7)与基本数据类型(i6)进行运算时会进行自动拆箱(i7=>int类型),比较的是两个基本数据类型的值。
“==”是一种比较运算符也是运算Integer num = 100; int primitive = 100; // num (Integer) 会被自动拆箱成 int (调用 num.intValue()) // 然后比较两个 int 值:100 == 100 System.out.println(num == primitive); // true
运算的类型:
false:两个都是包装类对象,不会自动拆箱,比较的是地址值。使用 new Integer() 创建的包装类对象地址不同。
false:基本数据类型赋值给包装类Java 会调用该包装类的 valueOf 方法自动装箱,但这题其实还是调用了new Integer() 创建一个新对象,像第二题一样,使用new创建的包装类地址不一样【后面会结合2.3.5题详细讲一下】
true:intValue()得到的是基本数据类型,“==”在基本数据类型里面就是比较的值
true:重头戏:结合第2.3.5题讲一下
先介绍一下 new Integer()和Integer.valueOf() 的区别
- new Integer():他总是在创建新的对象。每次使用 new
关键字,都会在堆(Heap)上创建一个全新的、独立的对象,无论值是否相同。不利用任何缓存。 - Integer.valueOf():他并不是每次都在创建新的对象。它内部使用了一个静态缓存池(cache pool),这个池预先创建并存储了从 -128 到 127 范围内的所有 Integer 对象。当调用Integer.valueOf(x)这个方法的时侯,他会先检查x的值在不在 -128 到127这个范围内,如果在它不会创建新对象,而是直接从缓存池中返回一个已有对象的引用,如果不在它才会调用 new Integer(x)创建一个新对象。
- 所以当我们使用Integer.valueOf()方法创建相同的对象(-128 到 127范围内)时,他们的地址是一样的。
// 比较两个包装类对象时,通常是比较引用(除非有特殊情况,如 Integer 缓存) Integer num1 = 100; Integer num2 = 100; // 由于 Integer 缓存了 -128 到 127 的值,num1 和 num2 的地址相同 System.out.println(num1 == num2); // true (在缓存范围内)
Integer num1 = 200; Integer num2 = 200; //200不在-128 到 127 的范围内,将调用new Integer创建新对象 System.out.println(num1 == num2); // false (new创建的地址不一样)
操作快捷键及注意事项
- new 类名()加上.var 然后回车会自动创建一个类,new Date().var => Date date = new Date();
- 当不理解某些类的时候可以Ctrl单击点进去查看方法的源码,可以自己用软件翻译一下上面的注释的解释
- 通过查看JDK文档和源码,可以更深入地理解这些类的设计原理和使用方法
- sout加上回车 => System.out.println()
变量名.sout+回车 => System.out.println(变量名) - Ctrl+d往下复制一行,光标放在想复制的那一行
总结
到此这篇关于Javase随机数类、日期类、包装类的基础知识的文章就介绍到这了,更多相关Javase随机数类、日期类、包装类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!