常用API
Object类
Object类的常见方法
方法名 | 说明 |
---|---|
public String toString() | 返回对象的字符串表示形式 |
public boolean equlas(Object o) | 判断两个对象是否相等 |
protected Object clone() | 对象克隆 |
1.1 toString方法
- 默认是返回当前对象在堆内存中的地址信息:类的全限名@内存地址
- toString存在的意义:父类toString()方法存在的意义就是为了被子类重写,以便返回对象的内容信息,而不是地址信息!!
1.2 equals方法
- 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false。但是比较两个对象的地址完全可以用“==”替代。
- equals存在的意义:为了被子类重写,以便子类自己来定制比较规则(比如比较对象内容)。
1.3 clone方法
-
当某个对象调用这个方法时,这个方法会复制一个一模一样的新对象返回。
-
Cloneable是一个接口,实现这个接口的类,可以被克隆。
-
浅克隆:拷贝出的新对象,与原对象中的数据一模一样(引用类型拷贝的只是地址)
-
深克隆:
- 对象中基本类型的数据直接拷贝。
- 对象中的字符串数据拷贝的还是地址。
- 对象中还包含的其他对象,不会拷贝地址,会创建新对象。
@Override protected Object clone() throws CloneNotSupportedException { // return super.clone(); //浅克隆 //深克隆 就是把数组重新克隆一份新的数组放入克隆的对象中 // 对象中基本类型的数据直接拷贝。 // 对象中的字符串数据拷贝的还是地址。 // 对象中还包含的其他对象,不会拷贝地址,会创建新对象。 User u1 = (User) super.clone(); double[] s1 = u1.scores.clone(); u1.scores=s1; return u1; }
Objects类
Objects类的常见方法
lObjects是一个工具类,提供了一些方法去完成一些功能。
方法名 | 说明 |
---|---|
public static boolean equals(Object a, Object b) | 比较两个对象的,底层会先进行非空判断,从而可以避免空指针异常。再进行equals比较 |
public static boolean isNull(Object obj) | 判断变量是否为null ,为null返回true ,反之返回false |
- 使用Objects的equals方法在进行对象的比较会更安全。可以避免空指针异常。
StringBuilder类
StringBuilder概述简介
- StringBuilder代表可变字符串对象,相当于是一个容器,它里面装的字符串是可以改变的,就是用来操作字符串的。
- 好处:StringBuilder比String更适合做字符串的修改操作,效率会更高,代码也会更简洁。频繁操作建议使用StringBuilder。StringBuilder会自动维护数组的扩容。(默认为16字符)
StringBuilder的构造方法
构造方法 | 说明 |
---|---|
public StringBuilder() | 创建一个空白的可变的字符串对象,不包含任何内容 |
public StringBuilder(String str) | 创建一个指定字符串内容的可变字符串对象 |
示例代码:
StringBuilder sb = new StringBuilder();
StringBuilder sb1 = new StringBuilder("我爱你");
StringBuilder常用方法
方法名称 | 说明 |
---|---|
public StringBuilder append(任意类型) | 添加数据并返回StringBuilder对象本身 |
public StringBuilder reverse() | 将对象的内容反转 |
public int length() | 返回对象内容长度 |
public String toString() | 通过toString()就可以实现把StringBuilder转换为String |
示例代码:
public class Demo {
public static void main(String[] args) {
//掌握StringBuilder的使用
//1、得到此对象
StringBuilder sb = new StringBuilder();
StringBuilder sb1 = new StringBuilder("我爱你");
//2、调用append()方法字符串追加 return this; 还是返回原来的对象
sb.append(1);
sb.append(3.14);
sb.append("中国");
System.out.println(sb);
//3、StringBilder支持链式编程
sb1.append("中国").append("love");
System.out.println(sb1);
//4、将对象内容反转
sb1.reverse().append("伟大");
System.out.println(sb1);
System.out.println(sb1.length());
//5、toString()方法,将StringBuilder对象转换成String字符串
String s = sb1.toString();
System.out.println(s);
}
}
注意:如果操作字符串较少,或者不需要操作,以及定义字符串变量,还是建议用String。
StringBuilder和StringBuffer
- StringBuffer的用法与StringBuilder是一模一样的但 StringBuilder是线程不安全的StringBuffer是线程安全的。
- StringBuffer比StringBulider方法上多一个synchronized这样的一个修饰符
补充
-
String为什么是不可变的?
我看过源代码,String类中一个byte[]数组,这个byte[]数组采用了final修饰,private final byte[] value;
因为数组一旦创建长度不可变。并且被final修饰的引用一旦指向了某个对象之后,不可以
再指向其他对象,所以String是不可变的!
”abc“无法变成”abcd“ -
StringBuilder/StringBuffer为什么是可变的?
我看过源代码,StringBuffer/StringBuilder内部实际上是一个byte[]数组,这个byte[]数组没有被final修饰,StringBuffer/StringBuilder的初始化容量我记得是16.当存满之后会进行扩容,底层调用了数组拷贝的方法
System.arraycopy()…是这样扩容的。所以StringBuffer/StringBuilder适合于使用字符串的频繁拼接操作
StringJoiner类
StringJoiner概述简介
- JDK8开始才有的,跟StringBuilder一样,也是用来操作字符串的,也可以看成是一个容器,创建之后里面的内容是可变的。
- 好处:不仅能提高字符串的操作效率,并且在有些场景下使用它操作字符串,代码会更简洁。
相关构造方法
构造器 | 说明 |
---|---|
public StringJoiner (间隔符号) | 创建一个StringJoiner对象,指定拼接时的间隔符号 |
public StringJoiner (间隔符号,开始符号,结束符号) | 创建一个StringJoiner对象,指定拼接时的间隔符号、开始符号、结束符号 |
常用方法
构造器 | 说明 |
---|---|
public StringJoiner add (要添加的字符序列) | 添加数据,并返回对象本身 |
public int length() | 返回长度 ( 字符出现的个数) |
public String toString() | 返回一个字符串(该字符串就是拼接之后的结果) |
代码示例:
public class Demo {
public static void main(String[] args) {
//理解StringJoiner的使用
int[] arr1={11,22,33};
System.out.println(getArrayData(arr1));
int[] arr2=null;
System.out.println(getArrayData(arr2));
int[] arr3={};
System.out.println(getArrayData(arr3));
}
public static String getArrayData(int[] arr){
if (Objects.isNull(arr)){
return null;
}
StringJoiner sj = new StringJoiner(", ", "[", "]");
for (int i = 0; i < arr.length; i++) {
sj.add(arr[i]+"");
}
return sj.toString();
}
}
Math类
Math类的常用方法
方法名 | 说明 |
---|---|
public static int abs(int a) | 获取参数绝对值 |
public static double ceil(double a) | 向上取整 |
public static double floor(double a) | 向下取整 |
public static int round(float a) | 四舍五入 |
public static int max(int a,int b) | 获取两个int值中的较大值 |
public static double pow(double a,double b) | 返回a的b次幂的值 |
public static double random() | 返回值为double的随机值,范围[0.0,1.0) |
代码示例:
public class MathDemo {
public static void main(String[] args) {
//1、 public static int abs(int a){}:绝对值
System.out.println(Math.abs(10));
System.out.println(Math.abs(-10));
// public static double ceil(double a):向上取整
System.out.println(Math.ceil(-10.8));//5.0
System.out.println(Math.ceil(4.0));//4.0
//public static double floor(double a) :向下取整
System.out.println(Math.floor(4.49999));
System.out.println(Math.floor(4.0));
// 4、public static long round(double a):四舍五入
System.out.println(Math.round(3.4999)); // 3
System.out.println(Math.round(3.50001)); // 4
// 5、public static int max(int a, int b):取较大值
// public static int min(int a, int b):取较小值
System.out.println(Math.max(10, 20)); // 20
System.out.println(Math.min(10, 20)); // 10
// 6、 public static double pow(double a, double b):取次方
System.out.println(Math.pow(2, 3)); // 2的3次方 8.0
System.out.println(Math.pow(3, 2)); // 3的2次方 9.0
// 7、public static double random(): 取随机数 [0.0 , 1.0) (包前不包后)
System.out.println(Math.random());
System.out.println(Math.random());
// 8.开平方
System.out.println(Math.sqrt(16)); // 4.0
}
}
System类
System代表程序所在的系统,也是一个工具类。
System类常见方法
方法名 | 说明 |
---|---|
public static void exit(int status) | 终止当前运行的Java虚拟机。 |
public static long currentTimeMillis() | 返回当前系统的时间毫秒值形式 |
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) | 将数组中指定的数据拷贝到另一个数组中。 |
代码示例:
public class SystemDemo {
public static void main(String[] args) {
System.out.println("程序开始");
// 目标:了解下System类的常见方法。
// 1、public static void exit(int status):
// 终止当前运行的Java虚拟机。
// 该参数用作状态代码; 按照惯例,非零状态代码表示异常终止。
//System.exit(0); // 了解一下即可,开发中不要使用
// 2、public static long currentTimeMillis():
// 获取当前系统的时间
// 返回的是long类型的时间毫秒值:指的是从1970-1-1 0:0:0开始走到此刻的总的毫秒值,1s = 1000ms
long time = System.currentTimeMillis();
System.out.println(time);
// 这个方法的作用:可以用来记录程序执行消耗的时间
long begin = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
System.out.println("Hello");
}
long end = System.currentTimeMillis();
System.out.println("程序执行花费的时间为:" + (end - begin) / 1000.0 + "秒");
System.out.println("程序结束");
}
}
arraycopy方法示例:
public class SystemDemo{
public static void main(String[] args){
int[] oldarr={1,2,3,4};
int[] newarr={5,6,7,8};
System.arraycopy(oldarr,0,newarr,0,4);
System.out.println(Arrays.toString(oldarr));//1234
System.out.println(Arrays.toString(newarr));//1234
}
}
Runtime类
代表程序所在的运行环境。Runtime是一个单例类。
Runtime类的常见方法
方法名 | 说明 |
---|---|
public static Runtime getRuntime() | 返回与当前Java应用程序关联的运行时对象 |
public void exit(int status) | 终止当前运行的虚拟机 |
public int availableProcessors() | 返回Java虚拟机可用的处理器数。 |
public long totalMemory() | 返回Java虚拟机中的内存总量 |
public long freeMemory() | 返回Java虚拟机中的可用内存 |
public Process exec(String command) | 启动某个程序,并返回代表该程序的对象 |
代码示例:
public class RuntimeDemo {
public static void main(String[] args) throws IOException, InterruptedException {
// 目标:了解下Runtime的几个常见方法。
// 1、public static Runtime getRuntime() 返回与当前Java应用程序关联的运行时对象。
Runtime r = Runtime.getRuntime();
// 2、public void exit(int status) 终止当前运行的虚拟机,该参数用作状态代码; 按照惯例,非零状态代码表示异常终止。
// r.exit(0);
// 3、public int availableProcessors(): 获取虚拟机能够使用的处理器数。
System.out.println(r.availableProcessors()); // 8
// 4、public long totalMemory() 返回Java虚拟机中的内存总量, 以字节为单位。
System.out.println(r.totalMemory() / 1024.0 / 1024.0 + "MB"); // 128.0MB
// 5、public long freeMemory() 返回Java虚拟机中的可用内存量
System.out.println(r.freeMemory() / 1024.0 / 1024.0 + "MB"); // 124.5192031860352MB
// 6、public Process exec(String command) 启动某个程序,并返回代表该程序的对象。
r.exec("D:\\qq\\Bin\\QQ.exe");
}
}
BigDecimal类
BigDecimal类的构造器
构造器 | 说明 |
---|---|
public BigDecimal(double val) 注意:不推荐使用这个 | 将 double转换为 BigDecimal |
public BigDecimal(String val) | 把String转成BigDecimal |
注意:不建议使用参数为小数的构造器,因为依然会存在精度失真问题
BigDecimal类的常用方法
方法名 | 说明 |
---|---|
public static BigDecimal valueOf(double val) | 转换一个 double成 BigDecimal |
public BigDecimal add(BigDecimal b) | 加法 |
public BigDecimal subtract(BigDecimal b) | 减法 |
public BigDecimal multiply(BigDecimal b) | 乘法 |
public BigDecimal divide(BigDecimal b) | 除法 |
public BigDecimal divide (另一个BigDecimal对象,精确几位,舍入模式) | 除法、可以控制精确到小数几位 |
public double doubleValue() | 将BigDecimal转换为double |
除法运算还可以设置舍入模式
BigDecimal divide = bd1.divide(参与运算的对象, 小数点后精确到多少位, 舍入模式);
参数1 ,表示参与运算的BigDecimal 对象。
参数2 ,表示小数点后面精确到多少位
参数3 ,舍入模式
RoundingMode.CEILING 进一法
RoundingMode.FLOOR 去尾法
RoundingMode.ROUND_HALF_UP 四舍五入
代码示例:
public class Demo {
public static void main(String[] args) {
// 目标:掌握BigDecimal进行精确运算的方案。
// 把浮点型数据封装成BigDecimal对象,再来参与运算。
// a、public BigDecimal(double val) 得到的BigDecimal对象是无法精确计算浮点型数据的。 注意:不推荐使用这个,
// b、public BigDecimal(String val) 得到的BigDecimal对象是可以精确计算浮点型数据的。 可以使用。
// c、public static BigDecimal valueOf(double val): 通过这个静态方法得到的BigDecimal对象是可以精确运算的。是最好的方案。
// 浮点型运算的时候直接+ * / 可能会出现数据失真(精度问题)。
System.out.println(0.09 + 0.01);
System.out.println(1.0 - 0.32);
System.out.println(1.015 * 100);
System.out.println(1.301 / 100);
System.out.println("========");
double a = 0.1;
double b = 0.2;
double c = a + b;
System.out.println(c); // 0.30000000000000004
System.out.println("--------------------------");
// 1、把浮点型数据封装成BigDecimal对象,再来参与运算。
// 使用BigDecimal规避浮点数运算过程中可能出现的精度失真问题
// 不建议使用参数为小数的构造器,因为依然会存在精度失真问题
// BigDecimal a1 = new BigDecimal(a);
// BigDecimal b1 = new BigDecimal(b);
// BigDecimal rs1 = a1.add(b1); //System.out.println(rs1);//0.3000000000000000166533453693773481063544750213623046875
// 下面这两种得到对象的方式可以完美地解决精度失真问题
BigDecimal m = new BigDecimal("0.1");
BigDecimal n = BigDecimal.valueOf(0.2);
// 2、public BigDecimal add(BigDecimal augend): 加法
BigDecimal rs2 = m.add(n);
System.out.println(rs2);//0.3
// 3、public BigDecimal subtract(BigDecimal augend): 减法
BigDecimal rs3 = m.subtract(n);
System.out.println(rs3);//-0.1
// 4、public BigDecimal multiply(BigDecimal augend): 乘法
BigDecimal rs4 = m.multiply(n);
System.out.println(rs4);//0.02
// 5、public BigDecimal divide(BigDecimal b): 除法
BigDecimal rs5 = m.divide(n);
System.out.println(rs5);//0.5
//注意:BigDecimal是一定要保证精度运算
BigDecimal x = BigDecimal.valueOf(10.0);
BigDecimal y = BigDecimal.valueOf(3.0);
// BigDecimal rs6 = x.divide(y);
//除不尽的情况,会报异常。
// System.out.println(rs6);//java.lang.ArithmeticException: Non-terminating decimal expansion;
// 6、public BigDecimal divide(另一个BigDecimal对象,精确几位,舍入模式) : 除法,可以设置精确几位。
BigDecimal rs6 = x.divide(y, 2, RoundingMode.CEILING);//向上取整
System.out.println(rs6);
// 7、public double doubleValue() : 把BigDecimal对象又转换成double类型的数据。
}
}
Date日期类
Date构造器
构造器 | 说明 |
---|---|
public Date() | 创建一个Date对象,代表的是系统当前此刻日期时间。 |
public Date(long time) | 把时间毫秒值转换成Date日期对象。 |
Date常用方法
常见方法 | 说明 |
---|---|
public long getTime() | 返回从1970年1月1日 00:00:00走到此刻的总的毫秒数 |
public void setTime(long time) | 设置日期对象的时间为当前时间毫秒值对应的时间 |
代码示例:
public class Demo {
public static void main(String[] args) {
//创建一个Date对象,代表系统当前时间信息
Date d = new Date();
System.out.println(d);
//2、拿到时间毫秒值
long time = d.getTime();
System.out.println(time);
//如果单纯想当前毫秒值,可以使用这个
System.out.println(System.currentTimeMillis());
//3、把时间毫秒值转换成日期时间
Date date1 = new Date(time);
System.out.println(date1);
System.out.println("=====");
//2s之后的时间是多少
long time1 = time+2000;
Date date2 = new Date(time1);
System.out.println(date2);
//也可以加两秒
d.setTime(time1+2000);
System.out.println(d);
}
}
SimpleDateFormat日期格式化类
SimpleDateFormat构造器
构造器 | 说明 |
---|---|
public SimpleDateFormat(String pattern) | 创建简单日期格式化对象,并封装格式化的形式信息 |
格式化方法
格式化方法 | 说明 |
---|---|
public final String format(Date date) | 将日期格式化成日期/时间字符串 |
public final String format(Object time) | 将时间毫秒值格式化成日期/时间字符串 |
常用格式化模式:
- yyyy-MM-dd HH:mm:ss
- yyyy年MM月dd日 HH:mm:ss
代码示例:
public class Demo {
public static void main(String[] args) {
//掌握SimpleDateFormat简单日期格式化类的使用
Date d = new Date();
long time = d.getTime();
System.out.println(d);
System.out.println(time);
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//SSS毫秒 E星期 a上午还是下午
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS E a");
String rs1 = sdf.format(d);
String rs2 = sdf.format(time);
System.out.println(rs1);
System.out.println(rs2);
解析方法
解析方法 | 说明 |
---|---|
public Date parse(String source) | 把字符串时间解析成日期对象 |
代码示例:
public class Demo2 {
public static void main(String[] args) throws ParseException {
//掌握SimpleDateFormat
String dateStr="2022-12-16 16:16:40";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date parse = sdf.parse(dateStr);
System.out.println(parse);
}
}
秒杀活动案例
需求
-
小贾下单并付款的时间为:2023年11月11日 0:01:18
-
小皮下单并付款的时间为:2023年11月11日 0:10:51
-
请用代码判断出这两位同学是否秒杀成功?
代码示例:
public class Demo3 {
public static void main(String[] args) throws ParseException, ParseException {
// 需求:模拟秒杀活动
// 1.记录四个时间
String startTime = "2023年11月11日 00:00:00";
String endTime = "2023年11月11日 00:10:00";
String xiaoJia = "2023年11月11日 0:01:18";
String xiaoPi = "2023年11月11日 0:10:51";
// 2.解析四个时间为日期对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date start = sdf.parse(startTime);
Date end = sdf.parse(endTime);
Date jia = sdf.parse(xiaoJia);
Date pi = sdf.parse(xiaoPi);
// 3.判断小贾和小皮是否秒杀成功
//第一种方法
if (jia.after(start)&&jia.before(end)){
System.out.println("小贾秒杀成功");
}else {
System.out.println("小贾秒杀失败");
}
//第二种方法
long start1 = start.getTime();
long end1 = end.getTime();
long jia1 = jia.getTime();
long pi1 = pi.getTime();
if (pi1>=start1&&pi1<=end1){
System.out.println("小皮秒杀成功");
}else {
System.out.println("小皮秒杀失败");
}
}
}
Calendar类
Calendar类概述与简介
- 代表的是系统此刻时间对应的日历
- 通过它可以单独获取、修改时间中的年、月、日、时、分、秒等。
- 注意:Calendar是可变对象,一旦修改后其对象本身表示的时间将产生变化。
Calendar日历类的常见方法
方法名 | 说明 |
---|---|
public static Calendar getInstance() | 获取当前日历对象 |
public int get(int field) | 获取日历中的某个信息。 |
public final Date getTime() | 获取日期对象。 |
public long getTimeInMillis() | 获取时间毫秒值 |
public void set(int field,int value) | 修改日历的某个信息。 |
public void add(int field,int amount) | 为某个信息增加/减少指定的值 |
代码示例:
public class CalendarDemo {
public static void main(String[] args) {
// 目标:掌握Calendar的使用和特点。
// 1、得到系统此刻时间对应的日历对象。
Calendar c = Calendar.getInstance();
System.out.println(c);
// 2、获取日历的信息:public int get(int field):取日期中的某个字段信息。
System.out.println(c.get(Calendar.MONTH));
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.WEEK_OF_YEAR));
System.out.println(c.get(Calendar.HOUR_OF_DAY));
// 3、拿到日历中记录的日期对象。
Date time = c.getTime();
System.out.println(time);
// 4、拿到时间毫秒值
long timeInMillis = c.getTimeInMillis();
System.out.println(timeInMillis);
// 5、修改日历中的某个信息
// Calendar是可变日期对象,一旦修改,它记录的日期时间将发生改变
c.set(Calendar.YEAR,2099);
System.out.println(c.get(Calendar.YEAR));
// 6、为某个信息增加或者减少多少
c.add(Calendar.HOUR_OF_DAY,-5);
System.out.println(c.get(Calendar.HOUR_OF_DAY));
}
}
JDK8新增API
JDK8之前传统的时间API和JDK8之后新增时间API的比较:
-
JDK8之前
-
设计不合理,使用不方便,很多都被淘汰了。
-
都是可变对象,修改后会丢失最开始的时间信息。
-
线程不安全。
-
只能精确到毫秒。
-
-
JDK8之后
- 设计更合理,功能丰富,使用更方便。
- 都是不可变对象,修改后会返回新的时间对象,不会丢失最开始的时间。
- 线程安全。
- 能精确到毫秒、纳秒。
LocalDate、LocalTime、LocalDateTime
获取对象的方法
-
public static Xxxx now();获取系统当前时间对应的该对象
- LocalDate ld = LocalDate.now();
- LocalTime it = LocalTime.now();
- LocalDateTime ldt = LocalDateTine.now();
-
public static Xxxx of(…);获取指定时间
- LocalDate localDate = LocalDate.of(2099,11,11);
- LocalTime localTime = LocalTime.of(9,8,59);
- LocalDateTime localDateTime = LocalDateTime.of(2025,11,11,14,30,01);
LocalDate
LocalDate常用API(都是处理年、月、日、星期相关的)
方法名 | 说明 |
---|---|
public int geYear() | 获取年 |
public int getMonthValue() | 获取月份(1-12) |
public int getDayOfMonth() | 获取日 |
public int getDayOfYear() | 获取当前是一年中的第几天 |
Public DayOfWeek getDayOfWeek() | 获取星期几:ld.getDayOfWeek().getValue() |
方法名 | 说明 |
---|---|
withYear、withMonth、withDayOfMonth、withDayOfYear | 直接修改某个信息,返回新日期对象 |
plusYears、plusMonths、plusDays、plusWeeks | 把某个信息加多少,返回新日期对象 |
minusYears、minusMonths、minusDays,minusWeeks | 把某个信息减多少,返回新日期对象 |
equals、isBefore、isAfter | 判断两个日期对象,是否相等,在前还是在后 |
注意:每次修改之后都会返回新的对象,原来的对象没有发生改变。
代码示例:
public class Demo1_LocalDate {
public static void main(String[] args) {
// 0、获取本地日期对象(不可变对象)
//都是不可变对象,修改后会返回新的时间对象,不会丢失最开始的时间。
LocalDate ld = LocalDate.now();
System.out.println(ld);
// 1、获取日期对象中的信息
int year = ld.getYear(); // 年
int month = ld.getMonthValue(); // 月(1-12)
int month1 = ld.getMonth().getValue();
int day = ld.getDayOfMonth(); // 日
int dayOfYear = ld.getDayOfYear(); // 一年中的第几天
int dayOfWeek = ld.getDayOfWeek().getValue(); // 星期几
System.out.println(year);
System.out.println(month);
System.out.println(" "+month1);
System.out.println(day);
System.out.println(dayOfYear);
System.out.println(dayOfWeek);
System.out.println("==========================================");
// 2、直接修改某个信息: withYear、withMonth、withDayOfMonth、withDayOfYear
// JDK8新增的日期时间对象都是不可变的对象,每次修改都返回了一个新对象,原来的对象并没有发生改变
LocalDate ld2 = ld.withYear(2099);
System.out.println(ld2); // 2099-12-16
System.out.println(ld); // 2022-12-16
LocalDate ld3 = ld.withMonth(10);
System.out.println(ld3); // 2022-10-16
// 3、把某个信息加多少: plusYears、plusMonths、plusDays、plusWeeks
LocalDate ld4 = ld.plusDays(5);
System.out.println(ld4); // 2022-12-21
// 4、把某个信息减多少:minusYears、minusMonths、minusDays、minusWeeks
LocalDate ld5 = ld.minusYears(5);
System.out.println(ld5); // 2017-12-16
// 5、获取指定日期的LocalDate对象: public static LocalDate of(int year, int month, int dayOfMonth)
LocalDate ld1 = LocalDate.of(2099, 11, 11);
LocalDate ld6 = LocalDate.of(2099, 11, 20);
// 6、判断2个日期对象,是否相等,在前还是在后: equals isBefore isAfter
System.out.println(ld1.equals(ld6)); // false
System.out.println(ld1.isBefore(ld6)); // true
System.out.println(ld1.isAfter(ld6)); // false
}
}
LocalTime
LocalTime的常用API(都是处理时、分、秒、纳秒相关的)
方法名 | 说明 |
---|---|
public int getHour() | 获取小时 |
public int getMinute() | 获取分 |
public int getSecond() | 获取秒 |
public int getNano() | 获取纳秒 |
方法名 | 说明 |
---|---|
withHour、withMinute、withSecond、withNano | 修改时间,返回新时间对象 |
plusHours、plusMinutes、plusSeconds、plusNanos | 把某个信息加多少,返回新时间对象 |
minusHours、minusMinutes、minusSeconds、minusNanos | 把某个信息减多少,返回新时间对象 |
equals isBefore isAfter | 判断2个时间对象,是否相等,在前还是在后 |
代码示例:
public class Demo2_LocalTime {
public static void main(String[] args) {
// 0、获取本地时间对象
//都是不可变对象,修改后会返回新的时间对象,不会丢失最开始的时间。
LocalTime lt = LocalTime.now(); // 时 分 秒 纳秒 不可变的
System.out.println(lt);
// 1、获取时间中的信息
int hour = lt.getHour(); //时
int minute = lt.getMinute(); //分
int second = lt.getSecond(); //秒
int nano = lt.getNano(); //纳秒
// 2、修改时间:withHour、withMinute、withSecond、withNano
LocalTime lt3 = lt.withHour(10);
LocalTime lt4 = lt.withMinute(10);
LocalTime lt5 = lt.withSecond(10);
LocalTime lt6 = lt.withNano(10);
// 3、加多少:plusHours、plusMinutes、plusSeconds、plusNanos
LocalTime lt7 = lt.plusHours(10);
LocalTime lt8 = lt.plusMinutes(10);
LocalTime lt9 = lt.plusSeconds(10);
LocalTime lt10 = lt.plusNanos(10);
// 4、减多少:minusHours、minusMinutes、minusSeconds、minusNanos
LocalTime lt11 = lt.minusHours(10);
LocalTime lt12 = lt.minusMinutes(10);
LocalTime lt13 = lt.minusSeconds(10);
LocalTime lt14 = lt.minusNanos(10);
// 5、获取指定时间的LocalTime对象:
// public static LocalTime of(int hour, int minute, int second)
LocalTime lt15 = LocalTime.of(12, 12, 12);
LocalTime lt16 = LocalTime.of(12, 12, 12);
// 6、判断2个时间对象,是否相等,在前还是在后: equals isBefore isAfter
System.out.println(lt15.equals(lt16)); // true
System.out.println(lt15.isAfter(lt)); // false
System.out.println(lt15.isBefore(lt)); // true
}
}
LocalDateTime
方法名 | 说明 |
---|---|
getYear、getMonthValue、getDayOfMonth、getDayOfYear getDayOfWeek、getHour、getMinute、getSecond、getNano | 获取年月日、时分秒、纳秒等 |
withYear、withMonth、withDayOfMonth、withDayOfYear withHour、withMinute、withSecond、withNano | 修改某个信息,返回新日期时间对象 |
plusYears、plusMonths、plusDays、plusWeeks plusHours、plusMinutes、plusSeconds、plusNanos | 把某个信息加多少,返回新日期时间对象 |
minusYears、minusMonths、minusDays、minusWeeks minusHours、minusMinutes、minusSeconds、minusNanos | 把某个信息减多少,返回新日期时间对象 |
equals isBefore isAfter | 判断2个时间对象,是否相等,在前还是在后 |
LocalDateTime的转换成LocalDate、LocalTime
方法名 | 说明 |
---|---|
public LocalDate toLocalDate() | 转换成一个LocalDate对象 |
public LocalTime toLocalTime() | 转换成一个LocalTime对象 |
代码示例:
public class Demo3_LocalDateTime {
public static void main(String[] args) {
// 0、获取本地日期和时间对象。
//都是不可变对象,修改后会返回新的时间对象,不会丢失最开始的时间。
LocalDateTime ldt = LocalDateTime.now(); // 年 月 日 时 分 秒 纳秒
System.out.println(ldt);
// 1、可以获取日期和时间的全部信息
int year = ldt.getYear(); // 年
int month = ldt.getMonthValue(); // 月
int day = ldt.getDayOfMonth(); // 日
int dayOfYear = ldt.getDayOfYear(); // 一年中的第几天
int dayOfWeek = ldt.getDayOfWeek().getValue(); // 获取是周几
int hour = ldt.getHour(); //时
int minute = ldt.getMinute(); //分
int second = ldt.getSecond(); //秒
int nano = ldt.getNano(); //纳秒
// 2、修改时间信息:
// withYear withMonth withDayOfMonth withDayOfYear withHour
// withMinute withSecond withNano
LocalDateTime ldt2 = ldt.withYear(2029);
LocalDateTime ldt3 = ldt.withMinute(59);
// 3、加多少:
// plusYears plusMonths plusDays plusWeeks plusHours plusMinutes plusSeconds plusNanos
LocalDateTime ldt4 = ldt.plusYears(2);
LocalDateTime ldt5 = ldt.plusMinutes(3);
// 4、减多少:
// minusDays minusYears minusMonths minusWeeks minusHours minusMinutes minusSeconds minusNanos
LocalDateTime ldt6 = ldt.minusYears(2);
LocalDateTime ldt7 = ldt.minusMinutes(3);
// 5、获取指定日期和时间的LocalDateTime对象:
// public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour,
// int minute, int second, int nanoOfSecond)
LocalDateTime ldt8 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);
LocalDateTime ldt9 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);
System.out.println(ldt8);
// 6、 判断2个日期、时间对象,是否相等,在前还是在后: equals、isBefore、isAfter
System.out.println(ldt9.equals(ldt8));
System.out.println(ldt9.isAfter(ldt));
System.out.println(ldt9.isBefore(ldt));
// 7、可以把LocalDateTime转换成LocalDate和LocalTime
// public LocalDate toLocalDate()
// public LocalTime toLocalTime()
// public static LocalDateTime of(LocalDate date, LocalTime time)
LocalDate ld = ldt.toLocalDate();
LocalTime lt = ldt.toLocalTime();
LocalDateTime ldt10 = LocalDateTime.of(ld, lt);
System.out.println(ldt10);
}
}
Zoneld、ZonedDateTime
Zoneld时区的常见方法
方法名 | 说明 |
---|---|
public static Set getAvailableZoneIds() | 获取Java中支持的所有时区 |
public static ZoneId systemDefault() | 获取系统默认时区 |
public static ZoneId of(String zoneId) | 获取一个指定时区 |
ZonedDateTime带时区时间的常见方法
方法名 | 说明 |
---|---|
public static ZonedDateTime now() | 获取当前时区的ZonedDateTime对象 |
public static ZonedDateTime now(ZoneId zone) | 获取指定时区的ZonedDateTime对象 |
getYear、getMonthValue、getDayOfMonth、getDayOfYeargetDayOfWeek、getHour、getMinute、getSecond、getNano | 获取年月日、时分秒、纳秒等 |
public ZonedDateTime withXxx(时间) | 修改时间系列的方法 |
public ZonedDateTime minusXxx(时间) | 减少时间系列的方法 |
public ZonedDateTime plusXxx(时间) | 增加时间系列的方法 |
代码示例:
public class Demo4_ZoneId_ZonedDateTime {
public static void main(String[] args) {
// 目标:了解时区和带时区的时间。
// 1、ZoneId的常见方法:
// public static ZoneId systemDefault(): 获取系统默认的时区
ZoneId z = ZoneId.systemDefault();
System.out.println(z.getId());
System.out.println(z.toString());
System.out.println(z);
// public static Set<String> getAvailableZoneIds(): 获取Java支持的全部时区Id
Set<String> ids = ZoneId.getAvailableZoneIds();
System.out.println(ids);
// public static ZoneId of(String zoneId) : 把某个时区id封装成ZoneId对象。
ZoneId z1 = ZoneId.of("Canada/Yukon");
System.out.println(z1);
// 2、ZonedDateTime:带时区的时间。
// public static ZonedDateTime now(ZoneId zone): 获取某个时区的ZonedDateTime对象。
ZonedDateTime now = ZonedDateTime.now(z1);
System.out.println(now);
// 获取世界标准时间
ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());
System.out.println(now1);
// public static ZonedDateTime now():获取系统默认时区的ZonedDateTime对象
ZonedDateTime now2 = ZonedDateTime.now();
System.out.println(now2);
// 获取日期时间中的相关信息
System.out.println(now2.getHour());
System.out.println(now2.getDayOfWeek());
System.out.println(now2.getDayOfMonth());
// 修改日期时间中的相关信息
ZonedDateTime zdt = now2.withYear(2088);
System.out.println(zdt.getYear());
}
}
Instant
Instant时间线上的某个时刻/时间戳
通过获取Instant的对象可以拿到此刻的时间,该时间由两部分组成:从1970-01-01 00:00:00 开始走到此刻的总秒数 + 不够1秒的纳秒数。
方法名 | 说明 |
---|---|
public static Instant now() | 获取当前时间的Instant对象(标准时间) |
public long getEpochSecond() | 获取从1970-01-01T00:00:00开始记录的秒数。 |
public int getNano() | 从时间线开始,获取从第二个开始的纳秒数 |
plusMillis plusSeconds plusNanos | 增加时间系列的方法 |
minusMillis minusSeconds minusNanos | 减少时间系列的方法 |
equals、isBefore、isAfter | 判断系列的方法 |
- 作用:可以用来记录代码的执行时间,或用于记录用户操作某个事件的时间点。
- 传统的Date类,只能精确到毫秒,并且是可变对象;
- 新增的Instant类,可以精确到纳秒,并且是不可变对象,推荐用Instant代替Date。
public class Demo5_Instant {
public static void main(String[] args) {
// 1、创建Instant的对象,获取此刻时间信息
Instant now = Instant.now();
System.out.println(now);
// 2、获取总秒数
long seconds = now.getEpochSecond();
System.out.println(seconds);
// 3、不够1秒的纳秒数
int nano = now.getNano();
System.out.println(nano);
// 4、增加、减少系列的方法
Instant a = now.plusSeconds(10);
System.out.println(a);
Instant b = now.minusNanos(10);
// 5、判断系列的方法
System.out.println(a.equals(b));
System.out.println(a.isBefore(b));
System.out.println(a.isAfter(b));
// Instant对象的作用:做代码的性能分析,或者记录用户的操作时间点
Instant start = Instant.now();
//代码....
Instant end = Instant.now();
//一般采用
// long l = System.currentTimeMillis();
}
}
DateTimeFormatter
DateTimeFormatter(代替SimpleDateFormat):格式化器,用于时间的格式化、解析
SimpleDateFormat是线程不安全的
DateTimeFormatter是线程安全的
方法名 | 说明 |
---|---|
public static DateTimeFormatter ofPattern(时间格式) | 获取格式化器对象 |
public String format(时间对象) | 格式化时间 |
代码示例:
public class Demo6_DateTimeFormatter {
public static void main(String[] args) {
//获取现在时间
LocalDateTime ldt = LocalDateTime.now();
// 1、创建一个日期时间格式化器对象出来。
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
// 2、对时间进行格式化
// 正向格式化
System.out.println(ldt);
String rs1 = dtf.format(ldt);
System.out.println(rs1);
// 反向格式化
String rs2 = ldt.format(dtf);
System.out.println(rs2);
// 3、解析时间:解析时间一般使用LocalDateTime提供的解析方法来解析。
String dateStr = "2029年12月12日 12:12:11";
LocalDateTime ldt2 = LocalDateTime.parse(dateStr, dtf);
System.out.println(ldt2);
}
}
Period、Duration
Period
可以用于计算两个 LocalDate对象 相差的年数、月数、天数。
方法名 | 说明 |
---|---|
public static Period between(LocalDate start, LocalDate end) | 传入2个日期对象,得到Period对象 |
public int getYears() | 计算隔几年,并返回 |
public int getMonths() | 计算隔几个月,年返回 |
public int getDays() | 计算隔多少天,并返回 |
代码示例:
public class Demo7_Period {
public static void main(String[] args) {
//可以用于计算两个 LocalDate对象 相差的年数、月数、天数。
// 目标:掌握Period的作用:计算机两个日期相差的年数,月数、天数。
LocalDate start = LocalDate.of(2029, 8, 10);
LocalDate end = LocalDate.of(2029, 12, 15);
// 1、创建Period对象,封装两个日期对象。
Period p = Period.between(start, end);
// 2、通过period对象获取两个日期对象相差的信息。
System.out.println(p.getYears());
System.out.println(p.getMonths());
System.out.println(p.getDays());
}
}
Duration
可以用于计算两个时间对象相差的天数、小时数、分数、秒数、纳秒数;支持LocalTime、LocalDateTime、Instant等时间。
方法名 | 说明 |
---|---|
public static Duration between(开始时间对象1,截止时间对象2) | 传入2个时间对象,得到Duration对象 |
public long toDays() | 计算隔多少天,并返回 |
public long toHours() | 计算隔多少小时,并返回 |
public long toMinutes() | 计算隔多少分,并返回 |
public long toSeconds() | 计算隔多少秒,并返回 |
public long toMillis() | 计算隔多少毫秒,并返回 |
public long toNanos() | 计算隔多少纳秒,并返回 |
代码示例:
public class Demo8_Duration {
public static void main(String[] args) {
LocalDateTime start = LocalDateTime.of(2025, 11, 11, 11, 10, 10);
LocalDateTime end = LocalDateTime.of(2025, 11, 11, 12, 11, 11);
// 1、得到Duration对象
Duration d = Duration.between(start, end);
// 2、获取两个时间对象间隔的信息
System.out.println(d.toDays());
System.out.println(d.toHours());
System.out.println(d.toMinutes());
System.out.println(d.toSeconds());
System.out.println(d.toMillis());//毫秒
System.out.println(d.toNanos());//纳秒
}
}
String字符串类
简介
java.lang.String 代表字符串 封装字符串数据 处理字符串
String创建对象封装字符串数据的方式:
- 方式一:Java程序中的所有字符串文字(例如:“abc”)都为此类的对象。
- 方式二:调用String类的构造器初始化字符串对象。
String类对象的特点:不可变性
-
每次试图改变字符串对象实际上是产生了新的字符串对象,变量每次都是指向了新的字符串对象,之前字符串对象的内容确实是没有改变的,因此说String的对象是不可变的。
-
注意:经过运算得到的字符串对象,会在堆内存中存储。
-
例:
String name="Hello"; name+="world"; name+="你好";
-
构造方法
构造器 | 说明 |
---|---|
public String() | 创建一个空白字符串对象,不含有任何内容 |
public String(String o) | 根据传入的字符串内容,来创建字符串对象 |
public String(char[] chars) | 根据字符数组的内容,来创建字符串对象 |
public String(byte[] bytes) | 根据字节数组的内容,来创建字符串对象 |
代码示例:
String str1="黑马";
System.out.println(str1);
String str2 = new String();
System.out.println(str2);
//public String(String original) 根据传入的字符串内容,来创建字符串对象 开发几乎不用
String str3 = new String("abc");
System.out.println(str3);
//public String(char[] chs) 根据字符数组的内容,来创建字符串对象
char[] chs={'a','b','c'};
String str4 = new String(chs);
System.out.println(str4);
//public String(byte[] chs)根据字节数组的内容,来创建字符串对象
byte[] bytes={65,66,67};
String str5 = new String(bytes);
System.out.println(str5);
String类对象在内存中的存储原理
- 只要以”…“方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份;
- 但通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。
字符串的内容的比较
推荐使用String类提供的”equals“方法比较:只关心内容一样
方法名 | 说明 |
---|---|
public boolean equals(Object obj) | 将此字符串与指定对象进行比较。只关心字符内容是否一致 |
public boolean equalsIgnoreCase(String s) | 将此字符串与指定对象进行比较,忽略大小写比较字符串。只关心字符内容是否一致 |
注意:字符串的内容比较不适合用”“比较,字符串用”“比较的是地址。”==“一般用于基本数据类型比较。
案例:
public class Demo2 {
public static void main(String[] args) {
// 模拟用户登录,系统记住正确密码,让用户输入自己的密码,如果输入正确,提示登录成功,否则提示登录失败
String sysPassword = "itheima";
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的密码:");
String password = sc.next();
// 字符串内容必须要使用equals方法
if (sysPassword.equals(password)) {
System.out.println("恭喜您,登录成功");
} else {
System.out.println("您输入的密码不正确");
}
// equalsIgnoreCase(String str): 忽略大小写比较字符串内容
String str1 = "abeRtQf";
String str2 = "ABERTqf";
System.out.println(str1.equals(str2)); // false
System.out.println(str1.equalsIgnoreCase(str2)); // true
}
}
String提供的操作字符串数据的常用方法
代码示例:
public class Demo3 {
public static void main(String[] args) {
String str = "我爱你中国love";
// 1、public int length(): 获取字符串的长度
int length = str.length(); // 9
System.out.println(length);
// 2、public char charAt(int index): 获取某个索引位置处的字符
System.out.println(str.charAt(1)); // 爱
System.out.println(str.charAt(4)); // 国
// 注意:访问的索引在字符串中必须存在,会报错:
// System.out.println(str.charAt(10)); // StringIndexOutOfBoundsException: 字符串索引越界异常
System.out.println("=====");
// 结合上面两个API,遍历字符串中的字符
for (int i = 0; i < str.length(); i++) {
System.out.println(str.charAt(i));
}
System.out.println("=====");
// 3、public char[] toCharArray(): 把字符串转换成字符数组
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.println(chars[i]);
}
System.out.println("=====");
// 我爱你中国love
// 4、public String substring(int beginIndex, int endIndex) :截取内容,(包前不包后的)
System.out.println(str.substring(3, 5)); // 中国
// 5、public String substring(int beginIndex):从当前索引一直截取到末尾
System.out.println(str.substring(5)); // love
// 6、public String replace(CharSequence target, CharSequence replacement):使用新值,将字符串中的旧值替换,得到新的字符串
String str1 = "垃圾电影,这个电影真垃圾,太垃圾了";
String str2 = str1.replace("垃圾", "**");
System.out.println(str1); // 垃圾电影,这个电影真垃圾,太垃圾了
System.out.println(str2); // **电影,这个电影真**,太**了
// 7、public boolean contains(CharSequence s):判断字符串中是否包含了某个字符串
System.out.println(str1.contains("垃圾")); // true
System.out.println(str2.contains("垃圾")); // false
// 8、public boolean startsWith(String prefix):判断字符串是否以某个字符串内容开头
System.out.println(str1.startsWith("垃圾")); // true
System.out.println(str2.startsWith("垃圾")); // false
System.out.println(str1.startsWith("垃圾电影,这个电影真垃圾,太垃圾了")); // true
// 9、public String[] split(String s): 按照某个内容把字符串分割成字符串数组返回
String str3 = "Angelababy,张三,李四,王五";
String[] names = str3.split(",");
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}
// 10、public String trim():删除字符串首尾空格,返回一个新字符串
String str5 = " 中国 伟大 ";
System.out.println(str5);
System.out.println(str5.trim());
// 11、public String toUpperCase():将此 String所有字符转换为大写
String str6 = "AsdwSDwe";
System.out.println(str6.toUpperCase()); // ASDWSDWE
System.out.println(str6.toLowerCase()); // asdwsdwe
}
}
String小案例
-
使用String开发验证码的生成
需求:随机产生验证码,可以是数字、大写字母、小写字母。
代码示例:
public class Test3 { public static void main(String[] args) { String code = createCode(5); System.out.println(code); } public static String createCode(int n){ String code=""; String data="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; //随机数对象 Random r = new Random(); for (int i = 0; i < n; i++) { int index = r.nextInt(data.length()); code+=data.charAt(index); } return code; } }
-
手机号码隐藏
需求:自己录入一个手机号隐藏中间四位输出。
代码示例:
public class Test4 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入一个手机号码:"); String phoneNo = scanner.next(); //截取前三位和后四位 String prefix = phoneNo.substring(0, 3); String suffix = phoneNo.substring(7); String result=prefix+"****"+suffix; System.out.println("加密后的手机号码为:"+result); } }
String str6 = “AsdwSDwe”;
System.out.println(str6.toUpperCase()); // ASDWSDWE
System.out.println(str6.toLowerCase()); // asdwsdwe
}
}
## String小案例
1. 使用String开发验证码的生成
需求:随机产生验证码,可以是数字、大写字母、小写字母。
代码示例:
```java
public class Test3 {
public static void main(String[] args) {
String code = createCode(5);
System.out.println(code);
}
public static String createCode(int n){
String code="";
String data="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//随机数对象
Random r = new Random();
for (int i = 0; i < n; i++) {
int index = r.nextInt(data.length());
code+=data.charAt(index);
}
return code;
}
}
-
手机号码隐藏
需求:自己录入一个手机号隐藏中间四位输出。
代码示例:
public class Test4 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入一个手机号码:"); String phoneNo = scanner.next(); //截取前三位和后四位 String prefix = phoneNo.substring(0, 3); String suffix = phoneNo.substring(7); String result=prefix+"****"+suffix; System.out.println("加密后的手机号码为:"+result); } }