不需要死记硬背,知道有,想得起来用,具体翻阅API帮助文档即可。
1. 基础类型对应的8个包装类
1.1 包装类概述
首先,包装类都是引用数据类型。
其次,包装类主要提供了更多的实用操作,这样更容易处理基本类型。
所有的包装类都是 final 的,所以不能创建其子类,包装类都是不可变对象。
装箱与拆箱:
装箱:基本数据类型—>引用数据类型【通过包装类的构造方法】
拆箱:引用数据类型—>基本数据类型【通过包装类引用.xxxValue()方法】
1.2 类层次结构
除了 Boolean
和 Character
外,其它的包装类都有 valueOf()
和 parseXXX()
方法,并且还具有byteVaue()
,shortVaue()
,intValue()
,longValue()
,floatValue()
和 doubleValue()
方法,这些方法是最常用的方法。
示例代码如下:
package numbertest;
public class IntegerTest01 {
public static void main(String[] args) {
int i1 = 100;
Integer i2 = new Integer(i1); //装箱
double i3 = i2.doubleValue(); //拆箱
float i4 = i2.floatValue(); //拆箱
String s = "123";
int i5 = Integer.parseInt(s); //将内容为数字的字符串转换为int类型
Integer i6 = new Integer(s);// 注意:如果这里s中不是数字,则虽然编译可以通过,
// 但是在运行阶段会出现NumberFormatException(数字格式化异常)
Integer i7 = Integer.valueOf(123); //也可以当做一种装箱的方式
Integer i8 = Integer.valueOf(s); //将内容为数字的字符串转换为Integer类型,必须是数字字符串才行,不然出现NumberFormatException(数字格式化异常)
}
}
Boolean的拆箱方法:booleanValue();
Character的拆箱方法:charValue();
1.3 包装类的常量
通过访问包装类的常量来获取该数据类型的最大值和最小值,通过Integer提供的常量获取int的最大值和最小值:
最大值:Integer.MAX_VALUE
最小值:Integer.MIN_VALUE
package numbertest;
public class IntegerTest02 {
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
System.out.println(Double.MAX_VALUE);
System.out.println(Double.MIN_VALUE);
}
}
运行结果:
当然,其它5个数字包装类也有对应的常量:
①byte最大值:Byte.MAX_VALUE
②byte最小值:Byte.MIN_VALUE
③short最大值:Short.MAX_VALUE
④short最小值:Short.MIN_VALUE
…
1.4 Integer的常用方法
- static int compare(int x, int y); 比较大小
- static int max(int a, int b); 最大值
- static int min(int a, int b); 最小值
- static int parseInt(String s); 将字符串数字转换成数字类型。其它包装类也有这个方法:Double.parseDouble(String s)
- static String toBinaryString(int i); 获取数字二进制的字符串表示形式
- static String toHexString(int i); 获取数字十六进制的字符串表示形式
- static String toOctalString(int i); 获取数字八进制的字符串表示形式
- int compareTo(Integer anotherInteger); 比较大小,可见实现了Comparable接口
- boolean equals(Object obj); 包装类已经重写了equals()方法。
- String toString(); 包装类已经重写了toString()方法。
- int intValue(); 将包装类拆箱为基本数据类型
- static String toString(int i); 将基本数据类型转换成字符串
- static Integer valueOf(int i); 将基本数据类型转换成Integer
- static Integer valueOf(String s) 将字符串转换成Integer(这个字符串必须是数字字符串才行,不然出现NumberFormatException)
1.5 JDK1.5 的新特性
在 JDK1.5 以前,包装类和基本类型做运算时,必须将包装类转换成基本类型才可以,而 JDK5.0提供 Auto-boxing/unboxing(自动装箱和拆箱)
- 自动将基础类型转换为对象;
- 自动将对象转换为基础类型。
如下代码:
package numbertest;
public class IntegerTest03 {
public static void main(String[] args) {
Integer i1 = new Integer(10); //装箱,jdk1.5前必须按该方式
Integer i2 = 10; // 自动装箱,jdk1.5及以后版本支持,当前为jdk1.8
int i3 = i1.intValue(); //拆箱,jdk1.5前必须按如下方式
int i4 = i1; //自动拆箱,jdk1.5及以后版本支持
System.out.println(i1 + 1); //这里的i1也会做自动拆箱
}
}
1.5.1 注意空指针异常
Integer a = null;
System.out.println(a + 1);
以上代码报空指针异常NullPointerException
,原因是a在进行自动拆箱时,会调用 a.intValue()
方法。因为a是null
,访问实例方法会出现空指针异常,因此使用时应注意。
1.6 int、Integer、String的互转
String,double,Double转换原理与上相同
1.7 整数型常量池
如下代码:
package numbertest;
public class IntegerTest04 {
public static void main(String[] args) {
Integer a = 128;
Integer b = 128;
System.out.println(a == b);
Integer x = 127;
Integer y = 127;
System.out.println(x == y);
}
}
运行结果:
java中为了提高程序的执行效率,将[-128, 127]范围内的所有256个包装对象提前创建好,放到一个方法区的“整数型常量池”中(池:就是Cache,缓存机制,消耗内存,提高速度),目的是只要用这个区间的数据就不用再new了,直接从整数型常量池中取出来。所以以上代码为先false
后true
。
2. 数字相关类
2.1 大整数BigInteger
当整数超过long的最大值,可以采用java.math.BigInteger
来解决,其父类为Number,BigInteger常用方法及示例:
- BigInteger add(BigInteger val); 求和
- BigInteger subtract(BigInteger val); 相减
- BigInteger multiply(BigInteger val); 乘积
- BigInteger divide(BigInteger val); 商
- int compareTo(BigInteger val); 比较
- BigInteger BigInteger abs(); 绝对值
- BigInteger max(BigInteger val); 最大值
- BigInteger min(BigInteger val); 最小值
- BigInteger pow(int exponent); 次幂
- BigInteger sqrt(); 平方根
package numbertest;
import java.math.BigInteger;
public class BigIntegerTest {
public static void main(String[] args) {
// long i = 12323435346546; //超出long类型,会报错
BigInteger i1 = new BigInteger("12323435346546");
BigInteger i2 = new BigInteger("2");
//加法
System.out.println(i1.add(i2));
//减法
System.out.println(i1.subtract(i2));
//乘法
System.out.println(i1.multiply(i2));
//除法
System.out.println(i1.divide(i2));
//求幂
BigInteger i3 = new BigInteger("2");
System.out.println(i3.pow(3));
//取更大的值
BigInteger i4 = new BigInteger("9");
System.out.println(i4.max(i3.pow(3)));
}
}
运行结果:
2.2 大浮点BigDecimal以及数字格式化DecimalFormat
- 当浮点型数据超过double的最大值,可以采用
java.math.BigDecimal
(经常用在财务软件中)来解决,其父类为Number,BigDecimal示例:
package decimaltest;
import java.math.BigDecimal;
public class BigDecimalTest01 {
public static void main(String[] args) {
BigDecimal v1 = new BigDecimal(10.2);
BigDecimal v2 = new BigDecimal(20.2);
//相加运算
BigDecimal v3 = v1.add(v2);
System.out.println(v3);
}
}
运行结果:
java.text.DecimalFormat
用于浮点数字格式化,DecimalFormat 示例:
package decimaltest;
import java.text.DecimalFormat;
public class DecimalTest01 {
public static void main(String[] args) {
// 加入千分位,保留两位小数
DecimalFormat df = new DecimalFormat("###,###.##"); //数字格式:#代表任意数字 ,代表千分位 .代表小数点
System.out.println(df.format(1234.23452));
//加入千分位,保留四位小数,不够补0
System.out.println(new DecimalFormat("###,###.0000").format(12345.12));
}
}
运行结果:
3. 日期相关类
3.1 常用日期类
- java.util.Date
- java.text.SimpleDateFormat
- java.util.Calendar
- java.util.Date 日期类
- 构造方法:Date()
- 构造方法:Date(long 毫秒)
- java.util.SimpleDateFormat 日期格式化类
- 日期转换成字符串(java.util.Date -> java.lang.String)
- 字符串转换成日期(java.lang.String -> java.util.Date)
- java.util.Calendar 日历类
- 获取当前时间的日历对象:Calendar c = Calendar.getInstance();
- 获取日历中的某部分:int year = c.get(Calendar.YEAR);
- Calendar.YEAR 获取年份
- Calendar.MONTH 获取月份,0表示1月,1表示2月,…,11表示12月
- Calendar.DAY_OF_MONTH 获取本月的第几天
- Calendar.DAY_OF_YEAR 获取本年的第几天
- Calendar.HOUR_OF_DAY 小时,24小时制
- Calendar.HOUR 小时,12小时制
- Calendar.MINUTE 获取分钟
- Calendar.SECOND 获取秒 Calendar.MILLISECOND 获取毫秒 Calendar.DAY_OF_WEEK 获取星期几,1表示星期日,…,7表示星期六
- 日历的set方法:设置日历 calendar.set(Calendar.YEAR, 2023); calendar.set(2008, Calendar.SEPTEMBER,8);
- 日历的add方法(日历中各个部分的加减): calendar.add(Calendar.YEAR, 1);
- 日历对象的setTime()让日历关联具体的时间 calendar.setTime(new Date());
- 日历对象的getTime()方法获取日历的具体时间: Date time = calendar.getTime();
示例代码如下:
package datetest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateTest01 {
public static void main(String[] args) throws ParseException {
// 获取今天的日期
Date today = new Date();
System.out.println(today);
//Date转换为String
//格式转换为日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(today));
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // 获取当前日期
//获取2024-02-28为星期几
Date d = new SimpleDateFormat("yyyy-MM-dd").parse("2024-02-28"); //String转换为Date,parse方法需要进行异常处理 这里选择throws ParseException
calendar.setTime(d); //Date转换为Calendar
System.out.println(calendar.get(Calendar.DAY_OF_WEEK));
}
}
运行结果:
3.2 System.currentTimeMillis();
System.currentTimeMillis();
获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数(时间戳),其可用于计算方法的执行时间。
Date的另一个构造方法:Date(long time)
,其中time表示毫秒数,Date d = new Date(1000*60*60*24);
获取的是1970年1月1日 00:00:00 000 加一天的时间,由于北京所在时区为东八区,所以最后转换出的时间为:1970年1月2日 08:00:00 000。
如下代码:
package datetest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.SimpleFormatter;
public class DateTest02 {
public static void main(String[] args) {
//获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数,
// 其可用于计算方法/代码段的执行时间
long time1 = System.currentTimeMillis();
System.out.println(time1);
for (int i = 0; i < 100; i++) {
System.out.print(i + " ");
}
System.out.println();
long time2 = System.currentTimeMillis();
System.out.println(time2-time1);
//其中time表示毫秒数,获取的是1970年1月1日 00:00:00 000 加一天的时间,
// 由于北京所在时区为东八区,所以最后转换出的时间为:1970年1月2日 08:00:00 000。
Date date = new Date(1000*60*60*24);
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
}
}
运行结果:
3.3 Java8的新日期API
上述传统的日期API存在线程安全问题,Java8又提供了一套全新的日期API。
java.time.LocalDate
、java.time.LocalTime
、java.time.LocalDateTime
日期、时间、日期时间
java.time.Instant
时间戳信息
java.time.Duration
计算两个时间对象之间的时间间隔,精度为纳秒
java.time.Period
计算两个日期之间的时间间隔,以年、月、日为单位。
java.time.temporal.TemporalAdjusters
提供了一些方法用于方便的进行日期时间调整
java.time.format.DateTimeFormatter
用于进行日期时间格式化和解析
3.3.1 LocalDate日期、LocalTime时间、LocalDateTime日期时间
- 获取当前时间(精确到纳秒,1秒=1000毫秒,1毫秒=1000微秒,1微秒=1000纳秒) LocalDateTime now = LocalDateTime.now();
- 获取指定日期时间 LocalDateTime ldt = LocalDateTime.of(2008,8,8,8,8,8,8); // 获取指定的日期时间
- 加日期和加时间 LocalDateTime localDateTime = ldt.plusYears(1).plusMonths(1).plusDays(1).plusHours(1).plusMinutes(1).plusSeconds(1).plusNanos(1);
- 减日期和减时间 LocalDateTime localDateTime = ldt.minusYears(1).minusMonths(1).minusDays(1).minusHours(1).minusMinutes(1).minusSeconds(1).minusNanos(1);
- 获取年月日时分秒
int year = now.getYear(); // 年
int month = now.getMonth().getValue(); // 月
int dayOfMonth = now.getDayOfMonth();// 一个月的第几天
int dayOfWeek = now.getDayOfWeek().getValue(); // 一个周第几天
int dayOfYear = now.getDayOfYear(); // 一年的第几天
int hour = now.getHour(); // 时 int minute = now.getMinute(); // 分
int second =now.getSecond(); // 秒
int nano = now.getNano(); // 纳秒
示例代码:
package newdatetest;
import java.time.LocalDateTime;
public class NewDateTest01 {
public static void main(String[] args) {
//获取系统当前时间,精确到纳秒
LocalDateTime now = LocalDateTime.now();
System.out.println("系统当前时间:" + now);
//获取指定的日期时间
LocalDateTime localDateTime = LocalDateTime.of(2024, 3, 10, 10, 10, 10, 10);
System.out.println(localDateTime);
//加日期时间
LocalDateTime localDateTime1 = localDateTime.plusYears(1);
System.out.println(localDateTime1);
//减日期时间
LocalDateTime localDateTime2 = localDateTime.minusDays(1);
System.out.println(localDateTime2);
//对象的链式调用
LocalDateTime localDateTime3 = localDateTime.minusYears(1).plusMonths(1).plusDays(1);
System.out.println(localDateTime3);
}
}
运行结果:
3.3.2 Instant 时间戳(获取1970年1月1日 0时0分0秒到某个时间的时间戳)
- 获取系统当前时间(UTC:全球标准时间):Instant instant = Instant.now();
- 获取时间戳:long epochMilli = instant.toEpochMilli();
示例代码:
package newdatetest;
import java.time.Instant;
public class NewDateTest02 {
public static void main(String[] args) {
//Java8前
long l = System.currentTimeMillis();
System.out.println("时间戳" + l);
//Java8的API
Instant now = Instant.now(); //系统当前时间,基于UTC(全球标准时间)
System.out.println(now);
//获取时间戳
long l1 = now.toEpochMilli();
System.out.println("时间戳" + l1);
}
}
运行结果:
3.3.3 Duration 计算时间间隔
- 计算两个时间相差时间间隔:
LocalDateTime now1 = LocalDateTime.of(2008,8,8,8,8,8);
LocalDateTime now2 = LocalDateTime.of(2009,9,9,9,9,9);
Duration between = Duration.between(now1, now2);
System.out.println(between.toHours()); // 两个时间差多少个小时
System.out.println(between.toDays()); // 两个时间差多少天
示例代码:
package newdatetest;
import java.time.Duration;
import java.time.LocalDateTime;
public class NewDateTest03 {
public static void main(String[] args) {
//获取时间1
LocalDateTime time1 = LocalDateTime.of(2024, 3, 9, 10, 10, 10);
//获取时间2
LocalDateTime time2 = LocalDateTime.of(2024, 4, 10, 10, 10, 10);
//获取两个时间的差
Duration duration = Duration.between(time1,time2);
//计算差多少天
System.out.println("相差天数:" + duration.toDays());
//计算差几个小时
System.out.println("相差小时数:" + duration.toHours());
}
}
运行结果:
3.3.4 Period 计算日期间隔
- 计算两个日期间隔:
LocalDate now1 = LocalDate.of(2007,7,7);
LocalDate now2 = LocalDate.of(2008,8,8);
Period between = Period.between(now1, now2);
System.out.println(between.getYears());// 相差年数
System.out.println(between.getMonths());// 相差月数
System.out.println(between.getDays());// 相差天数
示例代码:
package newdatetest;
import java.time.LocalDate;
import java.time.Period;
public class NewDateTest04 {
public static void main(String[] args) {
//获取日期
LocalDate date1 = LocalDate.of(2024,2,4);
LocalDate date2 = LocalDate.of(2024,3,2);
//计算两个日期差
Period period = Period.between(date1,date2);
//相差的年
System.out.println(period.getYears());
//相差的月
System.out.println(period.getMonths());
//相差的日
System.out.println(period.getDays());
}
}
运行结果:
3.3.5 TemporalAdjusters 时间矫正器
LocalDateTime now = LocalDateTime.now(); // 获取系统当前时间
now.with(TemporalAdjusters.firstDayOfMonth()); // 当前月的第一天
now.with(TemporalAdjusters.firstDayOfNextYear()); // 下一年的第一天
now.with(TemporalAdjusters.lastDayOfYear()); // 本年最后一天
now.with(TemporalAdjusters.lastDayOfMonth()); // 本月最后一天
now.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); // 下周一
示例代码:
package newdatetest;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
public class NewDateTest05 {
public static void main(String[] args) {
//获取系统当前时间
LocalDateTime now = LocalDateTime.now();
//矫正时间,当前月最后一天
LocalDateTime time1 = now.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(time1);
//当前月第一天
LocalDateTime time2 = now.with(TemporalAdjusters.firstDayOfMonth());
System.out.println(time2);
//下周一
LocalDateTime time3 = now.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
System.out.println(time3);
}
}
运行结果:
3.3.6 DateTimeFormatter 日期格式化
- 日期格式化 (LocalDateTime --> String)
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);
String s = dtf.format(now);- 将字符串转换成日期(String --> LocalDateTime)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);
LocalDateTime localDateTime = LocalDateTime.parse(“2008-08-08 08:08:08”, dtf);
System.out.println(localDateTime);
示例代码:
package newdatetest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class NewDateTest06 {
public static void main(String[] args) {
//1. LocalDateTime->String
//获取系统当前时间
LocalDateTime now = LocalDateTime.now();
//创建一个格式化对象
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//格式化
String s = dateTimeFormatter.format(now);
System.out.println(s);
//2.String->LocalDateTime
LocalDateTime time1 = LocalDateTime.parse("2024-03-11 14:35:23", dateTimeFormatter);
System.out.println(time1);
}
}
运行结果:
4. Math
java.lang.Math
数学工具类,都是静态方法。
- 常用属性:static final double PI(圆周率)
- 常用方法:
- static int abs(int a); 绝对值
- static double ceil(double a); 向上取整
- static double floor(double a); 向下取整
- static int max(int a, int b); 最大值
- static int min(int a, int b); 最小值
- static double random(); 随机数[0.0, 1.0)
int num = (int)(Math.random() * 100);可以获取[0-100)的随机数- static long round(double a); 四舍五入
- static double sqrt(double a); 平方根
- static double pow(double a, double b); a的b次幂
示例代码:
package mathtest;
public class MathTest {
public static void main(String[] args) {
//圆周率
System.out.println(Math.PI);
//绝对值
System.out.println(Math.abs(-34));
//向上取整
System.out.println(Math.ceil(2.5));
//向下取整
System.out.println(Math.floor(2.5));
//最大值
System.out.println(Math.max(2, 4));
//最小值
System.out.println(Math.min(3, 4));
//随机数
double v = Math.random() * 100; //获取[0-100)的随机数
System.out.println(v);
//四舍五入
System.out.println(Math.round(4.6));
//平方根
System.out.println(Math.sqrt(9));
//次幂
System.out.println(Math.pow(2, 3));
}
}
运行结果:
5. Random
Random 位于 java.util 包下,是可以产生随机数的工具类。常用方法:
- int nextInt(); 获取一个int类型取值范围[-2147483648,147483647]内的随机int数;
- int nextInt(int bound); 获取[0,bound)区间的随机数;
- double nextDouble(); 获取[0.0, 1.0)的随机数。
- 生成 5 个 0~100 之间的整数随机数(不包括100)
package randomtest;
import java.util.Random;
public class RandomTest01 {
public static void main(String[] args) {
Random random = new Random();
for (int i = 0; i < 5; i++) {
System.out.println(random.nextInt(100));
}
}
}
运行结果:
- 生成5个不重复的随机数
package randomtest;
import java.util.Random;
public class RandomTest02 {
public static void main(String[] args) {
//准备一个长度为5的数组,并给元素赋上默认值-1
int[] arr = {-1,-1,-1,-1,-1};
//创建随机数生成对象
Random random = new Random();
//循环生成随机数
int index = 0;
while (index < arr.length){
int num = random.nextInt(5);
if(!contains(arr,num)){
arr[index++] = num;
}
}
//遍历
for (int num: arr) {
System.out.println(num);
}
}
/**
* 判断数组arr中是否包含num
* @param arr
* @param num
* @return
*/
private static boolean contains(int[] arr, int num) {
for (int i = 0; i < arr.length; i++) {
if(arr[i] == num){
return true;
}
}
return false;
}
}
运行结果:
6. System系统类
- 常用属性:
- static final PrintStream err 标准错误输出流(System.err.println(“错误信息”);输出红色字体)
- static final InputStream in 标准输入流
- static final PrintStream out 标准输出流
- 常用方法:
- static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length); 数组拷贝
- static void exit(int status); 退出虚拟机
- static void gc(); 建议启动垃圾回收器
- static long currentTimeMillis(); 获取自1970-01-01 00:00:00 000到系统当前时间的总毫秒数
- static long nanoTime(); 获取自1970年1月1日0时0分0秒以来,当前时间的纳秒数
- static Map<String,String> getenv(); 获取当前系统的环境变量,例如Path,JAVA_HOME,CLASSPATH等。
- static Properties getProperties(); 获取当前系统的属性。
- static String getProperty(String key); 通过key获取指定的系统属性。
示例代码:
package systemtest;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;
public class SystemTest01 {
public static void main(String[] args) {
//标准输入流
System.out.println("1");
System.out.println(false);
System.out.println(2.1);
System.out.println(11111);
//与上等价
PrintStream printStream = System.out;
printStream.println("1");
printStream.println(false);
printStream.println(2.1);
printStream.println(11111);
//标准输入流
Scanner scanner1 = new Scanner(System.in);
//与上等价
InputStream inputStream = System.in;
Scanner scanner2 = new Scanner(inputStream);
//标准错误输出流(可搭配在异常中使用)
System.err.println("这是一个错误信息");
//处理除数不能为0的异常
try {
int a = 10;
int b = 0;
System.out.println(a/b);
}catch (ArithmeticException e){
System.err.println("除数不能为0!");
}
}
}
运行结果:
package systemtest;
import java.util.Map;
import java.util.Properties;
public class SystemTest02 {
public static void main(String[] args) {
//获取自1970-01-01 00:00:00 000(Unix元年)到系统当前时间的总毫秒数
long l = System.currentTimeMillis();
System.out.println(l);
//获取自1970-01-01 00:00:00 000(Unix元年)到系统当前时间的总纳秒数
long l2 = System.nanoTime();
System.out.println(l2);
//获取当前系统的环境变量
Map<String, String> getenv = System.getenv();
System.out.println(getenv);
System.out.println(getenv.get("Path"));
//获取当前系统的环境变量
Properties properties = System.getProperties();
System.out.println(properties);
//通过key获取指定的系统属性
String property = System.getProperty("os.name");
System.out.println(property);
}
}
运行结果:
1710058273220
1063101121114900
{USERDOMAIN_ROAMINGPROFILE=DESKTOP-RH6QTD1, LOCALAPPDATA=C:\Users\Sunnywang\AppData\Local, PROCESSOR_LEVEL=6, IntelliJ IDEA=D:\My_app\IntelliJ IDEA 2018.3.3\bin;, USERDOMAIN=DESKTOP-RH6QTD1, LOGONSERVER=\\DESKTOP-RH6QTD1, JAVA_HOME=D:\My_app\Java\jdk1.8.0_361, SESSIONNAME=Console, ALLUSERSPROFILE=C:\ProgramData, PROCESSOR_ARCHITECTURE=AMD64, PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules, SystemDrive=C:, asl.log=Destination=file, MAVEN_HOME=D:\Tools\Maven\apache-maven-3.5.2, OneDrive=C:\Users\Sunnywang\OneDrive, APPDATA=C:\Users\Sunnywang\AppData\Roaming, USERNAME=Sunnywang, ProgramFiles(x86)=C:\Program Files (x86), CommonProgramFiles=C:\Program Files\Common Files, Path=D:\My_app\VMware\VMware Workstation\bin\;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;D:\Interpreter\Python36\Scripts\;D:\Interpreter\Python36\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\iCLS\;C:\Program Files\Intel\Intel(R) Management Engine Components\iCLS\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\My_app\Bandizip\;D:\My_app\MatLab\R2021a\runtime\win64;D:\My_app\MatLab\R2021a\bin;D:\My_app\MatLab\R2021a\polyspace\bin;D:\Tools\PDFtk Server\bin\;D:\My_app\Java\jdk1.8.0_361\bin;D:\My_app\Java\jdk1.8.0_361\jre\bin;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\bin;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\include;C:\Users\ffmpeg\bin;D:\Tools\Maven\apache-maven-3.5.2\bin;C:\Users\Sunnywang\AppData\Local\Microsoft\WindowsApps;D:\Tools\Microsoft VS Code\bin;D:\My_app\IntelliJ IDEA 2018.3.3\bin;;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\bin;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\include;D:\My_app\texlive\2023\bin\windows, PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW, DriverData=C:\Windows\System32\Drivers\DriverData, OS=Windows_NT, COMPUTERNAME=DESKTOP-RH6QTD1, PROCESSOR_REVISION=8e0b, CLASSPATH=.;D:\My_app\Java\jdk1.8.0_361\lib\dt.jar;D:\My_app\Java\jdk1.8.0_361\lib\tools.jar;, CommonProgramW6432=C:\Program Files\Common Files, ComSpec=C:\WINDOWS\system32\cmd.exe, ProgramData=C:\ProgramData, ProgramW6432=C:\Program Files, HOMEPATH=\Users\Sunnywang, SystemRoot=C:\WINDOWS, TEMP=C:\Users\SUNNYW~1\AppData\Local\Temp, HOMEDRIVE=C:, PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 142 Stepping 11, GenuineIntel, USERPROFILE=C:\Users\Sunnywang, TMP=C:\Users\SUNNYW~1\AppData\Local\Temp, CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files, ProgramFiles=C:\Program Files, PUBLIC=C:\Users\Public, NUMBER_OF_PROCESSORS=8, windir=C:\WINDOWS, =::=::\, ZES_ENABLE_SYSMAN=1}
D:\My_app\VMware\VMware Workstation\bin\;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;D:\Interpreter\Python36\Scripts\;D:\Interpreter\Python36\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\iCLS\;C:\Program Files\Intel\Intel(R) Management Engine Components\iCLS\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\My_app\Bandizip\;D:\My_app\MatLab\R2021a\runtime\win64;D:\My_app\MatLab\R2021a\bin;D:\My_app\MatLab\R2021a\polyspace\bin;D:\Tools\PDFtk Server\bin\;D:\My_app\Java\jdk1.8.0_361\bin;D:\My_app\Java\jdk1.8.0_361\jre\bin;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\bin;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\include;C:\Users\ffmpeg\bin;D:\Tools\Maven\apache-maven-3.5.2\bin;C:\Users\Sunnywang\AppData\Local\Microsoft\WindowsApps;D:\Tools\Microsoft VS Code\bin;D:\My_app\IntelliJ IDEA 2018.3.3\bin;;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\bin;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\include;D:\My_app\texlive\2023\bin\windows
{java.runtime.name=Java(TM) SE Runtime Environment, sun.boot.library.path=D:\My_app\Java\jdk1.8.0_361\jre\bin, java.vm.version=25.361-b09, java.vm.vendor=Oracle Corporation, java.vendor.url=http://java.oracle.com/, path.separator=;, java.vm.name=Java HotSpot(TM) 64-Bit Server VM, file.encoding.pkg=sun.io, user.country=CN, user.script=, sun.java.launcher=SUN_STANDARD, sun.os.patch.level=, java.vm.specification.name=Java Virtual Machine Specification, user.dir=D:\workspace\IDEAProjects\Java_se, java.runtime.version=1.8.0_361-b09, java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment, java.endorsed.dirs=D:\My_app\Java\jdk1.8.0_361\jre\lib\endorsed, os.arch=amd64, java.io.tmpdir=C:\Users\SUNNYW~1\AppData\Local\Temp\, line.separator=
, java.vm.specification.vendor=Oracle Corporation, user.variant=, os.name=Windows 10, sun.jnu.encoding=GBK, java.library.path=D:\My_app\Java\jdk1.8.0_361\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;D:\My_app\VMware\VMware Workstation\bin\;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;D:\Interpreter\Python36\Scripts\;D:\Interpreter\Python36\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\iCLS\;C:\Program Files\Intel\Intel(R) Management Engine Components\iCLS\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\My_app\Bandizip\;D:\My_app\MatLab\R2021a\runtime\win64;D:\My_app\MatLab\R2021a\bin;D:\My_app\MatLab\R2021a\polyspace\bin;D:\Tools\PDFtk Server\bin\;D:\My_app\Java\jdk1.8.0_361\bin;D:\My_app\Java\jdk1.8.0_361\jre\bin;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\bin;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\include;C:\Users\ffmpeg\bin;D:\Tools\Maven\apache-maven-3.5.2\bin;C:\Users\Sunnywang\AppData\Local\Microsoft\WindowsApps;D:\Tools\Microsoft VS Code\bin;D:\My_app\IntelliJ IDEA 2018.3.3\bin;;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\bin;D:\Interpreter\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\include;D:\My_app\texlive\2023\bin\windows;., java.specification.name=Java Platform API Specification, java.class.version=52.0, sun.management.compiler=HotSpot 64-Bit Tiered Compilers, os.version=10.0, user.home=C:\Users\Sunnywang, user.timezone=, java.awt.printerjob=sun.awt.windows.WPrinterJob, file.encoding=UTF-8, java.specification.version=1.8, java.class.path=D:\My_app\Java\jdk1.8.0_361\jre\lib\charsets.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\deploy.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\access-bridge-64.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\cldrdata.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\dnsns.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\jaccess.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\jfxrt.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\localedata.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\nashorn.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\sunec.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\sunjce_provider.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\sunmscapi.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\sunpkcs11.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\ext\zipfs.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\javaws.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\jce.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\jfr.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\jfxswt.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\jsse.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\management-agent.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\plugin.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\resources.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\rt.jar;D:\workspace\IDEAProjects\Java_se\out\production\Java_se;D:\My_app\IntelliJ IDEA 2018.3.3\lib\idea_rt.jar, user.name=Sunnywang, java.vm.specification.version=1.8, sun.java.command=systemtest.SystemTest02, java.home=D:\My_app\Java\jdk1.8.0_361\jre, sun.arch.data.model=64, user.language=zh, java.specification.vendor=Oracle Corporation, awt.toolkit=sun.awt.windows.WToolkit, java.vm.info=mixed mode, java.version=1.8.0_361, java.ext.dirs=D:\My_app\Java\jdk1.8.0_361\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext, sun.boot.class.path=D:\My_app\Java\jdk1.8.0_361\jre\lib\resources.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\rt.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\jsse.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\jce.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\charsets.jar;D:\My_app\Java\jdk1.8.0_361\jre\lib\jfr.jar;D:\My_app\Java\jdk1.8.0_361\jre\classes, java.vendor=Oracle Corporation, java.specification.maintenance.version=4, file.separator=\, java.vendor.url.bug=http://bugreport.sun.com/bugreport/, sun.io.unicode.encoding=UnicodeLittle, sun.cpu.endian=little, sun.desktop=windows, sun.cpu.isalist=amd64}
Windows 10
Process finished with exit code 0
7. UUID的生成
UUID(通用唯一标识符)是一种软件构建的标准,用来生成具有唯一性的ID。具有以下特点:
- UUID可以在分布式系统中生成唯一的标识符,避免因为主键冲突等问题带来的麻烦。
- UUID具有足够的唯一性,重复的概率相当低。UUID使用的是128位数字,除了传统的16进制表示之外(32位的16进制表示),还有基于62进制的表示,可以更加简洁紧凑。
- UUID生成时不需要依赖任何中央控制器或数据库服务器,可以在本地方便、快速地生成唯一标识符。
- UUID生成后可以被许多编程语言支持并方便地转化为字符串表示形式,适用于多种应用场景。
在Java开发中,UUID的使用是非常普遍的。它可以用于生成数据表主键、场景标识、链路追踪、缓存Key等。使用UUID可以方便地避免主键、缓存Key等因冲突而产生的问题,同时能够实现多种功能,例如追踪、缓存、日志记录等。
Java中的java.util.UUID
类提供对UUID的支持
- 生成UUID:static UUID randomUUID();
- 将UUID转换为字符串:String toString();
import java.util.UUID;
public class UUIDTest {
public static void main(String[] args) {
//获取UUID对象
UUID uuid = UUID.randomUUID();
//将其转换为字符串
String s = uuid.toString();
System.out.println(s);
String s1 = s.replaceAll("-","");
System.out.println(s1);
}
}
运行结果:
8. 枚举(Java5新特性)
枚举(Enum)是一种引用数据类型,编译后也是生成.class文件。
先看如下代码:
package enumtest;
/**
* 以下程序不使用枚举类型,大家分析这个程序存在的问题,或者说,这个程序哪里可以改进?
* 两个问题:
* 第一个问题:可读性差。
* 第二个问题:错误没有在编译阶段提醒。
* 程序的设计有一个原则:
* 错误越早发现越好。完美的状态是:所有的错误,包括业务的错误尽可能在编译阶段检查出来。
*/
public class EnumTest01 {
public static void main(String[] args) {
int i = get();
switch (i){
case 1:
System.out.println("春季");
case 2:
System.out.println("夏季");
case 3:
System.out.println("秋季");
case 4:
System.out.println("冬季");
}
}
/**
* 这个方法可能会返回一个int类型值:
* 1 2 3 4
* @return
*/
public static int get(){
return 5; //这里没有返回1-4中的任一个数,按理应该有错误的
}
}
8.1 如何定义枚举
最基本的格式:
enum 枚举类型名 {
枚举值1, 枚举值2, 枚举值3, 枚举值4
}
8.2 什么情况下考虑使用枚举类型?
结果只有两种情况的,建议使用boolean类型;
结果超过两种情况且可以一一列举出来的,建议使用枚举类型。
- 合理使用枚举类型可以让代码更加清晰、可读性更高,可以有效地避免一些常见的错误。
- 枚举类型是类型安全的,它可以有效地防止使用错误的类型进行赋值。
- 通过反编译(javap)可以看到:
①所有枚举类型默认继承java.lang.Enum
,因此枚举类型无法继承其他类;
②所有的枚举类型都被final修饰,所以枚举类型是不可继承的;
③所有的枚举值都是常量;
④所有的枚举类型中都有一个values数组(可以通过values()获取所有枚举值并遍历)。
8.3 采用枚举改进
package enumtest;
/**
* 枚举类型:季节
*/
public enum Season{
// 直接定义枚举值,每一个枚举值可以看做类中的常量
SPRING,SUMMER,AUTUMN,WINTER
}
package enumtest;
import java.util.Arrays;
/**
* 使用枚举类型,分析优点:
* 第一个优点:可读性强了。
* 第二个优点:做了类型的限定,做了类型的检查,在编译阶段就确定了类型的安全。
*/
public class EnumTest02 {
public static void main(String[] args) {
//直接输出Season中的特定枚举值
System.out.println(Season.SPRING);
//获取Season中所有枚举值,并将返回的Season数组转换为String类型输出
System.out.println(Arrays.toString(Season.values()));
Season season = get();
switch (season){
case SPRING:
System.out.println("春季");
break;
case SUMMER:
System.out.println("夏季");
break;
case AUTUMN:
System.out.println("秋季");
break;
case WINTER:
System.out.println("冬季");
}
}
private static Season get() {
return Season.SPRING;
}
}
8.4 枚举的高级用法
- 普通类中可以编写的元素,枚举类型中也可以编写。包括静态代码块,构造代码块,实例方法,静态方法,实例变量,静态变量。
- 枚举类中的构造方法是私有化的(默认就是私有化的,只能在本类中调用)
构造方法调用时不能用new。直接使用“枚举值(实参);”调用。
每一个枚举值相当于枚举类型的实例。 - 枚举类型中如果编写了其他代码,必须要有枚举值,枚举值的定义要放到最上面,
最后一个枚举值的分号不能省略。 - 枚举类因为默认继承了
java.lang.Enum
,因此不能再继承其他类,但可以实现接口。
第一种实现方式:在枚举类中实现。
第二种实现方式:让每一个枚举值实现接口。
- 枚举中其他类型的定义
package enumtest;
/**
* 季节枚举
*
* 枚举高级用法,语法点:
* 1. 如果一个枚举类型中定义了普通类的东西,必须指定枚举值。
* 2. 枚举值的定义只能出现在类体的最上面。
* 3. 枚举值的最后面必须有“;”结尾。
*/
public enum Season{
/** 定义了有参数的构造方法之后
* 通过以下代码来调用构造方法
* 注意枚举类的构造方法不能使用new来调用。
* 并且枚举类的构造方法只能在本类中调用。
*/
//枚举值必须在最前面
SPRING("春季","春意盎然"),
SUMMER("夏季", "天太闷热"),
AUTUMN("秋季", "秋高气爽"),
WINTER("冬季", "白雪皑皑"); //这里的分号不能省略
// 实例变量
private final String name;
private final String desc;
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
Season(String name,String desc){
this.name = name;
this.desc = desc;
}
// 静态代码块
static {
System.out.println("枚举类型Season的静态代码块执行了");
}
// 构造代码块
{
System.out.println("构造代码块执行了");
}
// 静态变量
public final static int A = 10;
// 实例变量
private final int b = 20;
// 静态方法
public static int getA(){
return A;
}
// 实例方法
public int getB(){
return b;
}
}
package enumtest;
public class EnumTest03 {
public static void main(String[] args) {
//遍历
Season[] seasons = Season.values();
for (Season s:seasons) {
System.out.println(s.getName() + "-->" + s.getDesc());
}
Season season = get();
switch (season){
case SPRING:
System.out.println(Season.SPRING.getDesc());
break;
case SUMMER:
System.out.println(Season.SUMMER.getDesc());
break;
case AUTUMN:
System.out.println(Season.AUTUMN.getDesc());
break;
case WINTER:
System.out.println(Season.WINTER.getDesc());
}
//调用实例方法
System.out.println(season.getB());
//调用静态方法
System.out.println(Season.getA());
}
private static Season get() {
return Season.SUMMER;
}
}
运行结果:
- 枚举实现接口:
- 第一种实现方式:在枚举类中实现。
package enumtest;
public interface Eatable {
void eat();
}
package enumtest;
/**
* 枚举实现接口
*/
public enum Season implements Eatable{
//枚举值必须在最前面
SPRING("春季","春意盎然"),
SUMMER("夏季", "天太闷热"),
AUTUMN("秋季", "秋高气爽"),
WINTER("冬季", "白雪皑皑"); //这里的分号不能省略
// 实例变量
private final String name;
private final String desc;
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
Season(String name,String desc){
this.name = name;
this.desc = desc;
}
//在枚举类中实现接口
@Override
public void eat() {
System.out.println("四季都吃一样的!");
}
}
package enumtest;
public class EnumTest04 {
public static void main(String[] args) {
Season season = get();
switch (season){
case SPRING:
Season.SPRING.eat();
break;
case SUMMER:
Season.SUMMER.eat();
break;
case AUTUMN:
Season.AUTUMN.eat();
break;
case WINTER:
Season.WINTER.eat();
}
}
private static Season get() {
return Season.SUMMER;
}
}
运行结果:
- 第二种实现方式:让每一个枚举值实现接口。
package enumtest;
public interface Eatable {
void eat();
}
package enumtest;
/**
* 枚举实现接口
*/
public enum Season implements Eatable{
//枚举值必须在最前面
SPRING("春季","春意盎然"){
@Override
public void eat() {
System.out.println("春季吃苹果");
}
},
SUMMER("夏季", "天太闷热"){
@Override
public void eat() {
System.out.println("夏季吃西瓜");
}
},
AUTUMN("秋季", "秋高气爽"){
@Override
public void eat() {
System.out.println("秋季吃柚子");
}
},
WINTER("冬季", "白雪皑皑"){
@Override
public void eat() {
System.out.println("冬季吃草莓");
}
}; //这里的分号不能省略
// 实例变量
private final String name;
private final String desc;
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
Season(String name,String desc){
this.name = name;
this.desc = desc;
}
package enumtest;
public class EnumTest04 {
public static void main(String[] args) {
Season season = get();
switch (season){
case SPRING:
Season.SPRING.eat();
break;
case SUMMER:
Season.SUMMER.eat();
break;
case AUTUMN:
Season.AUTUMN.eat();
break;
case WINTER:
Season.WINTER.eat();
}
}
private static Season get() {
return Season.SUMMER;
}
}
运行结果: