8.实用类

1 实用类
1.1 枚举
Enum是一种有确定取值区间的数据类型,本质是一种类,具有简洁、安全、方便等特点。枚举的值被约束到一个特定的范围,只能取这个范围以内的值。
描述对象的一些属性特征时,可以选择的值是一个特定范围的,该属性的值不能随便定义。例如性别,只能是男女。
枚举就是一个特殊的类,它的对象只能从特定的范围内选取,而不能自定义,可以确保数据的安全性。
枚举通常由一组常量组成的类型,指定了一个取值区间,只能从该区间中取值。
java
public class week {
public static final int MONDAY = 1 ;
public static final int TUESDAY = 2;
public static final int WEDNESDAY = 3;
public static final int THURSDAY = 4;
public static final int FRIDAY = 5;
public static final int SATURDAY = 6;
public static final int SUNDAY = 7;
private week(){
}
}
java
public enum Week2 {
MONDAY, TUESDAY, WEDNESDAY,ThURSDAY, FRIDAY, SATURDAY, SUNDAY;
}
java
public class test {
public static void main(String[] args) {
System.out.println(week.MONDAY);
System.out.println(Week2.MONDAY);
}
}
1.2 数学类
Math类为开发这提供了一系列的数学方法,同时还提供了两个静态变量,一满足项目研发中对数学运算的要求,Math类中的所有方法都是静态的,通过类名直接调用
java
public class test {
public static void main(String[] args) {
System.out.println(Math.E);//自然常数
System.out.println(Math.PI);//圆周率
System.out.println(Math.sqrt(9));//开二次方
System.out.println(Math.cbrt(8));//开立方
System.out.println(Math.pow(2, 3));//2的三次方
System.out.println(Math.max(6.3, 3.5));//比大
System.out.println(Math.min(6.3, 3.5));//比小
System.out.println(Math.abs(-50));//绝对值
System.out.println(Math.ceil(10.0001));//比该值大的最小整数
System.out.println(Math.floor(10.9999));//比该值小的最大整数
System.out.println(Math.random());//随机数
System.out.println(Math.rint(5.6));//四舍五入
}
}
1.3 Random
Random是用来产生一个随机数的类,并且可以任意指定一个区间,在此区间产生一个随机数
| 方法 | 描述 |
|---|---|
| public Random() | 创建一个无参的随机数构造器,使用系统时间作为默认种子 |
| public Random(long seed) | 使用long数据类型的种子创建一个随机数构造器 |
| public boolean nextBoolean() | 返回一个随机的boolean值 |
| public double nextDouble() | 返回一个随机的double数据 |
| public float nextFloat() | 返回一个随机的float数据 |
| public int nextInt() | 返回一个随机的int数据 |
| public int nextInt(int n) | 返回一个从0到n之间的随机int数据 |
| public long nextLong() | 返回一个随机的long数据 |
| public synchronized void setSeed(long seed) | 使用单个long种子设置此随机数生成器的种子 |
1.4 String
String是实际开发总使用频率很高的类,Java通过String类来创建和操作字符串数据
String实例化
String实例化有两种方式
- 直接赋值
- 通过构造函数创建对象
字符对象底层使用字符数组来存储数据
例如Hello
char[] str = {‘H’, ’e’ , ’l’ , ’l’ , ’o’}
java
public class test {
public static void main(String[] args) {
//直接赋值
String s1 = "hello world";
//构造函数
String s2 = new String("hello world");
System.out.println(s1);
System.out.println(s2);
}
}
两种实例化的方式有何不同?哪种更好?
java
public class test {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2);
String s3 = new String("hello");
String s4 = new String("hello");
System.out.println(s3 == s4);
System.out.println(s1 == s3);
}
}
用直接赋值的方式创建了s1和s2,并且值相等,又使用了构造器的方式创建s3和s4,同样值相等
==判断的不是对象的值是否相等,而是判断对象所引用的内存地址是否相等
s1所引用的内存地址和s2所引用的内存地址相同,s1和s2指向堆内存中的同一块位置
s3和s4指向堆中的不同的位置
直接赋值的方式会在栈内存中开辟一块空间来存储s1
同时堆内存中开辟一块空间来存储hello,然后将堆内存的地址赋给栈内存的s1,s1中存储的是hello的内存地址
java在堆中提供了一个字符串常亮池,专门用来存储String对象
特点:在创建一个String对象的时候,首先会在字符串常量池中查找,如果该字符串已经在池中创建,则直接返回他的内存地址,如果字符串常量池中不存在该对象,先创建再返回
字符串常量池中不会创建值相等的重复字符串(字符串常量池只适用于直接赋值创建的方式,如果是通过构造器创建对象的方式则完全不同,这种方式创建的对象会在堆内存中直接开辟对应的空间来存储)
所以说根据以上的原因,我们在判断字符串之间是否相等的时候,我们使用equals方法来判断,equals方法是String基于继承的基础上进行了重写,逻辑就是只判断值是否相等
String常用方法
| 方法 | 描述 |
|---|---|
| public String() | 创建一个值为空的对象 |
| public String(String value) | 创建一个值为value的对象 |
| public String(char[] value) | 将一个char类型数组转为字符串对象 |
| public String(char[] value, int offset,int count) | 将一个指定范围的char类型数组转为字符串对象 |
| public String(byte[] bytes) | 将一个byte类型的数组转换为字符串对象 |
| public String(byte[] bytes, int offset, int count) | 将一个指定范围内的byte类型数组转换成字符串对象 |
| public int length() | 返回字符串的长度 |
| public boolean isEmpty() | 判断字符串是否为空 |
| public char charAt() | 返回的字符串中指定位置的字符 |
| public byte[] getByte() | 将字符串转为byte类型数组 |
| public boolean equals(Object obj) | 判断两个字符串是否相等 |
| public boolean equalsIgnoreCase(String str) | 判断两个字符串是否相等并且忽略大小写 |
| Public int compareTo(String str) | 对两个字符串进行排序 |
| public boolean startsWith(String str) | 判断是否以指定的值开头 |
| public boolean endsWith(String str) | 判断是否以指定的值结尾 |
| public int hashCode() | 获取字符串的散列值 |
| public int indexOf(String str) | 从头开始查找指定字符的位置 |
| public int indexOf(String str, int index) | 从指定的位置开始查找指定字符的位置 |
| public String substring(int index) | 截取字符串从指定位置开始到结尾 |
| public String substring(int index1, int index2) | 截取字符串从指定位置开始道指定位置结束 |
| public String concat(String str) | 追加字符串 |
| public String replaceAll(String str1, String str2) | 替换字符串 |
| public String[] split(String str) | 用指定的字符串对目标字符串进行分割,返回数组 |
| public String toLowerCase() | 将字符串转为小写 |
| public String toUpperCase() | 将字符串转为大写 |
| public char[] toCharArray() | 将字符串转为char数组 |
1.5 StringBuffer
实际开发中使用String会存在一个问题,String对象一旦创建,值是不能修改的
java
public class test {
public static void main(String[] args) {
String s1 = "hello";
System.out.println(s1);
s1 = "world!";
System.out.println(s1);
}
}
这里看似能改,其实在后面那个给s1赋值的时候,这个s1就已经不是前面的那个s1了,相当于创建了一个新的对象来存放world!。
String 底层是一个字符数组(JDK 8 及之前是 char[],JDK 9 之后改为 byte[]),并且这个数组被 private final 修饰。 2所以 String 对象一旦创建,底层存储就不能被修改,任何“修改字符串”的操作都会创建一个新的 String 对象。而且数组的特点是一旦创建长度不能修改。
如果开发中需要对某个字符串进行频繁的修改,使用string就不合适了会造成空间浪费的问题
所以我们用StringBuffer来解决,StringBuffer和String很类似,底层也是用一个数组来存储字符串的值,并且默认的长度为16,即一个空的StringBuffer对象数组长度为16
当我们调用构造器创建一个StringBuffer对象时,数组长度就不是16了,而是根据当前对象的值来决定数组的长度,指的长度加上16作为数组的长度
无论创建的StringBuffer对象是什么内容都会预留16个长度,就是用来修改的
| 方法 | 描述 |
|---|---|
| public StringBuffer() | 无参构造,创建一个空的StringBuffer对象 |
| public StringBuffer(String str) | 有参构造 |
| public synchronized int length() | 返回StringBuffer的长度 |
| public synchronized char charAt(int index) | 返回字符串中指定为的字符 |
| public synchronized StringBuffer append(String str) | 追加字符 |
| public synchronized StringBuffer delete(int start, int end) | 删除指定区间内的字符 |
| public synchronized StringBuffer deleteCharAt(int index) | 删除指定位置的字符 |
| public synchronized StringBuffer replace(int start, int end, String str) | 将指定区间内的值替换为str |
| public synchronized String substring(int start) | 截取字符串从指定位置开始到结尾 |
| public synchronized String substring(int start, int end) | 截取字符串从指定位置开始到指定位置结束 |
| public synchronized StringBuffer insert(int offset, String str) | 向指定位置插入str |
| public int indexOf(String str) | 从头开始查找指定字符的位置 |
| public int indexOf(String str,int index) | 从指定位置开始查找指定字符的位置 |
| public synchronized StringBuffer reverse() | 进行反转 |
| public synchronized String toString() | 返回StringBuffer对应的String |
1.6 日期类
Java对于日期的封装提供了良好的封装,包括java.util.Date和jav.util.calendar
1.7 Date
Date类使用比较简单,直接通过构造函数实例化对象即可,Date对象表示当前的系统时间,默认的格式不是我们所熟悉的,一般需要对它进行格式化处理,将日期的表示形式转换成我们所熟悉的方式
我们可以自定义日期的转换格式,SimpleDateFormat提供了模板标记
| 标记 | 描述 |
|---|---|
| y | 年,yyyy表示4位数的年份信息 |
| M | 月,MM表示2位数的月份信息 |
| m | 分钟,mm表示2位数的分钟信息 |
| d | 天,dd表示2位数的天信息 |
| H | 小时,HH表示2位数的24小时制下的小时信息 |
| h | 小时,hh表示2位数的12小时制下的小时信息 |
| s | 秒,ss表示2位数的秒信息 |
| S | 毫秒,SSS表示3位数的毫秒信息 |
java
public class test {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
System.out.println(sdf.format(date));
}
}
1.8 Calendar
通过Date类可以获取当前系统时间,但是功能也仅限榆次,如果需要对日期数据仅限逻辑操作
Date没有计算能力可以通过Calendar类来完成日期数据的逻辑运算
使用Calendar进行日期运算的基本思路是先将日期数据赋值给Calendar,再调用Calendar的方法来完成相关的运算
如何将日期赋值给Calendar,Calendar类提供了很多静态常量来记录日期数据
| 常量 | 描述 |
|---|---|
| public static final int YEAR | 年 |
| public static final int MONTH | 月 |
| public static final int DAY_OF_MONTH | 天,以月为单位,即当天是该月中的第几天 |
| public static final int DAY_OF_YEAR | 天,以年为单位,即当天是该年中的第几天 |
| public static final int HOUR_OF_DAY | 小时 |
| public static final int MINUTE | 分钟 |
| public static final int SECOND | 秒 |
| public static final int MILLISECOND | 毫秒 |
Calendar常用方法
| 方法 | 描述 |
|---|---|
| public static Calendar getInstance | 获取系统对应的Calendar实例化对象 |
| public void set(int field, int value) | 给静态常量赋值 |
| public int get(int field) | 获取静态常量的值 |
| public final Date getTime() | 获取Calendar对应的Date对象 |
java
public class test {
public static void main(String[] args) {
//计算2026-10-5所在的周是2026年的第几周
//将数据存入
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2026);
cal.set(Calendar.MONTH, 9);
cal.set(Calendar.DAY_OF_MONTH, 5);
//将数据取出
int i = cal.get(Calendar.WEEK_OF_YEAR);
System.out.println(i);
//两百天后是哪一年的几月几号
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.YEAR, 2026);
cal2.set(Calendar.MONTH, 9);
cal2.set(Calendar.DAY_OF_MONTH, 5);
int i2 = cal2.get(Calendar.DAY_OF_YEAR);
int n = i2 + 200;
cal2.set(Calendar.DAY_OF_YEAR, n);
Date date = cal2.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(date);
System.out.println(str);
}
}
1.9 java.time 日期时间 API
从 JDK 8 开始,Java 提供了 java.time 包,用来替代旧的 Date、Calendar 和 SimpleDateFormat。新 API 的类基本都是不可变的,线程更安全,使用也更直观。
| 类 | 描述 |
|---|---|
LocalDate |
表示日期,不包含时间和时区,例如 2026-10-05 |
LocalTime |
表示时间,不包含日期和时区,例如 14:30:00 |
LocalDateTime |
表示日期和时间,不包含时区 |
Instant |
表示时间轴上的一个瞬时点,常用于表示时间戳 |
Period |
表示基于日期的时间间隔,例如几年、几月、几天 |
Duration |
表示基于时间的时间间隔,例如几小时、几分、几秒 |
DateTimeFormatter |
用于格式化和解析日期时间,替代 SimpleDateFormat |
LocalDate 常用方法
| 方法 | 描述 |
|---|---|
LocalDate.now() |
获取当前日期 |
LocalDate.of(year, month, day) |
根据年月日创建日期对象 |
plusDays(long days) |
增加天数 |
plusMonths(long months) |
增加月数 |
plusYears(long years) |
增加年数 |
minusDays(long days) |
减少天数 |
getYear() |
获取年份 |
getMonthValue() |
获取月份,返回 1-12 |
getDayOfMonth() |
获取当月第几天 |
getDayOfWeek() |
获取星期 |
format(DateTimeFormatter formatter) |
将日期格式化为字符串 |
parse(CharSequence text) |
将字符串解析为日期对象使用示例 |
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class test {
public static void main(String[] args) {
// 获取当前日期
LocalDate today = LocalDate.now();
System.out.println("当前日期:" + today);
// 创建指定日期
LocalDate date = LocalDate.of(2026, 10, 5);
System.out.println("指定日期:" + date);
// 日期运算:两百天后是哪天
LocalDate future = date.plusDays(200);
System.out.println("两百天后:" + future);
// 格式化输出
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
System.out.println("当前时间:" + now.format(formatter));
}
}
| 旧 API | 新 API | 说明 |
|---|---|---|
Date |
LocalDate / LocalDateTime / Instant |
新 API 语义更清晰 |
Calendar |
LocalDate / LocalDateTime |
新 API 不需要 getInstance() |
SimpleDateFormat |
DateTimeFormatter |
新 API 线程安全 |
| 月份从 0 开始 | 月份从 1 开始 | 新 API 更符合直觉 |
| 可变、线程不安全 | 不可变、线程安全 | 新 API 更适合并发环境 |
在实际开发中,如果项目使用 JDK 8 及以上版本,建议优先使用 java.time 包中的类。

评论