Math
Math概述
- 是一个帮助我们进行数学计算的工具类
- 私有化构造方法,所有的方法都是静态的
Math类的常用方法
package com.itheima.test56;
public class Test {
public static void main(String[] args) {
System.out.println(isPrime(97));
}
public static boolean isPrime(int number) {
for (int i = 2; i <= Math.sqrt(number) ; i++) {
if (number % 2 == 0) {
return false;
}
}
return false;
}
}
package com.itheima.test56;
public class Test2 {
public static void main(String[] args) {
int count = 0;
for (int i = 100; i < 1000; i++) {
int a = i % 10;
int b = i / 10 % 10;
int c = i / 100;
if (i == Math.pow(a,3) + Math.pow(b,3) + Math.pow(c,3)) {
count++;
}
}
System.out.println(count);
}
}
System
System是一个工具类,提供了一些与系统相关的方法
- 时间原点:1970年1月1日00:00:00,我国在东八区,有8小时时差
- 1秒=1000毫秒
System.exit()
package com.itheima.test56;
public class Test3 {
public static void main(String[] args) {
// 0:虚拟机正常结束程序
// 非0:虚拟机非正常结束程序
System.exit(0);
System.out.println("看看我执行了吗");
}
}
运行结果:
System.currentTimeMills()
package com.itheima.test56;
public class test4 {
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
}
}
System.arraycopy(源数组,从源数组第几个索引开始,目的数组,从目的数组第几个索引开始,复制几个数据)
package com.itheima.test56;
public class Test5 {
public static void main(String[] args) {
int[] arr1 = {1, 2, 3, 4, 5, 6};
int[] arr2 = new int[6];
System.arraycopy(arr1,0,arr2,0,6);
for (int i = 0; i < arr2.length; i++) {
System.out.print(arr2[i] + " ");
}
}
}
运行结果:
Runtime
Runtime表示当前虚拟机的运行环境
package com.itheima.test56;
import java.io.IOException;
public class Test6 {
public static void main(String[] args) throws IOException {
// 停止虚拟机
Runtime.getRuntime().exit(0);
// 获取CPU的线程数字
System.out.println(Runtime.getRuntime().availableProcessors());
// JVM能从系统中获取的总内存大小
System.out.println(Runtime.getRuntime().maxMemory());
// JVM已经从系统中获取的总内存大小
System.out.println(Runtime.getRuntime().totalMemory());
// JVM剩余的内存大小
System.out.println(Runtime.getRuntime().freeMemory());
// 运行CMD命令
Runtime.getRuntime().exec("shutdown -a");
// notepad --> 跳出记事本
// shutdown -s -t 时间 --> 多少时间后关机
// shutdown -a --> 取消定时关机
}
}
Object
Object概述
Object是Java中的顶级父类。所有的类都直接或简洁的继承于Object类。
Object类中的方法可以被所有子类访问,所以我们要学习Object类和其中的方法。
Object的构造方法
Object的成员方法
toString()
package com.itheima.objectdemo;
public class ObjectDemo1 {
public static void main(String[] args) {
/*
public string tostring() 返回对象的字符串表示形式
public boolean equals(Object obj) 比较两个对象是否相等
protected object clone(int a) 对象克隆
*/
//1.tostring 返回对象的字符串表示形式
Object obj = new Object();
String str1 = obj.toString();
System.out.println(str1);//java.lang.Object@4e50df2e
Student stu = new Student();
String str2 = stu.toString();
System.out.println(str2);//如果没有重写Student中的toString方法,调用toString方法仍然会调用顶级父类Object的toString方法,com.itheima.objectdemo.Student@3c1
//细节:
System.out.println(stu);//com.itheima.objectdemo.Student@3c1
//细节:
//System:类名
//out:静态变量
//system.out:获取打印的对象
//println():方法
//参数:表示打印的内容
//核心逻辑:
//当我们打印一个对象的时候,底层会调用对象的tostring方法,把对象变成字符串。
//然后再打印在控制台上,打印完毕换行处理。
//思考:默认情况下,因为Object类中的tostring方法返回的是地址值
//所以,默认情况下,打印一个对象打印的就是地址值
//但是地址值对于我们是没什么意义的?
//我想要看到对象内部的属性值?我们该怎么办?
//处理方案:重写父类Object类中的toString方法
System.out.println(stu);//com.itheima.objectdemo.Student@3c1
//tostring方法的结论:
//如果我们打印一个对象,想要看到属性值的话,那么就重写tostring方法就可以了。
//在重写的方法中,把对象的属性值进行拼接。
}
}
如果在Student中没有重写toString方法,运行结果如下:
在Student中重写toString方法
public String toString() {
return name + ", " + age;
}
运行方法如下:
equals()
package com.itheima.objectdemo;
public class ObjectDemo2 {
public static void main(String[] args) {
/*
public boolean equals(Object obj) 比较两个对象是否相等
*/
Student s1 = new Student("zhangsan",23);
Student s2 = new Student("zhangsan",23);
boolean result1 = s1.equals(s2);
System.out.println(result1);//true
//结论:
//1.如果没有重写equals方法,那么默认使用Object中的方法进行比较,比较的是地址值是否相等
//2.一般来讲地址值对于我们意义不大,所以我们会重写,重写之后比较的就是对象内部的属性值了。
}
}
package com.itheima.objectdemo;
public class ObjectDemo3 {
public static void main(String[] args) {
String s = "abc";
StringBuilder sb = new StringBuilder("abc");
System.out.println(s.equals(sb));// false
//因为equals方法是被s调用的,而s是字符串
//所以equals要看string类中的
//字符串中的equals方法,先判断参数是否为字符串
// 如果是字符串,再比较内部的属性
//但是如果参数不是字符串,直接返回false
System.out.println(sb.equals(s));// false
//因为equals方法是被sb调用的,而sb是StringBuilder
//所以这里的equals方法要看StringBuilder中的equals方法
//那么在StringBuilder当中,没有重写equals方法
//使用的是Object中的
//在Object当中默认是使用==号比较两个对象的地址值
//而这里的s和sb记录的地址值是不一样的,所以结果返回false
}
}
对象克隆 clone()
把A对象的属性值完全拷贝给B对象,也叫对象拷贝、对象复制
浅克隆
不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来
深克隆
- 基本数据类型-->拷贝过来
- 字符串-->复用
- 引用数据类型-->重新创建新的小空间
Object的克隆是浅克隆,如果想要深克隆,需要重写克隆方法,在方法里面自行开辟一个新的空间,将对应的数据拷贝过去
package com.itheima.objectdemo;
import com.google.gson.Gson;
public class ObjectDemo4 {
public static void main(String[] args) throws CloneNotSupportedException {
// protected object clone(int a) 对象克隆
//1.先创建一个对象
int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
User u1 = new User(1, "zhangsan", "1234qwer", "girl11", data);
//2.克隆对象
//细节:
//方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去。
//书写细节:
//1.重写Object中的clone方法
//2.让javabean类实现Cloneable接口
//3.创建原对象并调用clone就可以了
User u2 =(User)u1.clone();
//验证一件事情:Object中的克隆是浅克隆
//想要进行深克隆,就需要重写clone方法并修改里面的方法体
int[] arr = u1.getData();
arr[0] = 100;
System.out.println(u1);// 角色编号为:1,用户名为:zhangsan密码为:1234qwer, 游戏图片为:girl11, 进度:[100, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]
System.out.println(u2);// 角色编号为:1,用户名为:zhangsan密码为:1234qwer, 游戏图片为:girl11, 进度:[100, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]
//以后一般会用第三方工具进行克隆
//1.第三方写的代码导入到项目中
//2.编写代码
// Gson gson =new Gson();
//把对象变成一个字符串
// String s=gson.toJson(u1);
//再把字符串变回对象就可以了
// User user =gson.fromJson(s, User.class);
// int[] arr=u1.getData();
// arr[0] = 100;
//打印对象
// System.out.println(user);// 角色编号为:1,用户名为:zhangsan密码为:1234qwer, 游戏图片为:girl11, 进度:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]
}
}
没有在User类中重写clone方法的话,运行结果如下:(会同时修改两个的数据)
深克隆有两种方法:
一种是自行重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
//调用父类中的clone方法
//相当于让Java帮我们克隆一个对象,并把克隆之后的对象返回出去。
//先把被克隆对象中的数组获取出来
int[] data = this.data;
//创建新的数组
int[] newData =new int[data.length];
//拷贝数组中的数据
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
//调用父类中的方法克隆对象
User u=(User)super.clone();
//因为父类中的克隆方法是浅克隆,替换克隆出来对象中的数组地址值
u.data =newData;
return u;
}
第二种是导入第三方库:
package com.itheima.objectdemo;
import com.google.gson.Gson;
public class ObjectDemo4 {
public static void main(String[] args) throws CloneNotSupportedException {
// protected object clone(int a) 对象克隆
//1.先创建一个对象
int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
User u1 = new User(1, "zhangsan", "1234qwer", "girl11", data);
//2.克隆对象
//细节:
//方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去。
//书写细节:
//1.重写Object中的clone方法
//2.让javabean类实现Cloneable接口
//3.创建原对象并调用clone就可以了
// User u2 =(User)u1.clone();
//验证一件事情:Object中的克隆是浅克隆
//想要进行深克隆,就需要重写clone方法并修改里面的方法体
// int[] arr = u1.getData();
// arr[0] = 100;
// System.out.println(u1);// 角色编号为:1,用户名为:zhangsan密码为:1234qwer, 游戏图片为:girl11, 进度:[100, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]
// System.out.println(u2);// 角色编号为:1,用户名为:zhangsan密码为:1234qwer, 游戏图片为:girl11, 进度:[100, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]
//以后一般会用第三方工具进行克隆
//1.第三方写的代码导入到项目中
//2.编写代码
Gson gson =new Gson();
//把对象变成一个字符串
String s=gson.toJson(u1);
//再把字符串变回对象就可以了
User user =gson.fromJson(s, User.class);
int[] arr=u1.getData();
arr[0] = 100;
//打印对象
System.out.println(user);// 角色编号为:1,用户名为:zhangsan密码为:1234qwer, 游戏图片为:girl11, 进度:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]
}
}
第三方库的原理就是先将原来对象里面的所有内容都转换成字符串的形式,然后再把字符串转换成对象的形式,这样子就相当于开辟了一个新的空间
总结
- Object是Java中的顶级父类
- 所有的类都直接或简洁的继承于Object类
- toString():一般会重写,打印对象时打印属性
- equals():比较对象时会重写,比较对象属性值是否相同
- clone():默认浅克隆
- 如果需要深克隆需要重写方法或者使用第三方工具类
Objects
Objects的成员方法
- Objects是一个对象工具类,提供了一些操作对象的方法
- equals(对象1,对象2):先做非空判断,比较两个对象
- isNull(对象):判断对象是否为空
- nonNull(对象):判断对象是否不为空
package com.itheima.objectsdemo;
import java.util.Objects;
public class ObjectsDemo1 {
public static void main(String[] args) {
/*
public static boolean equals(Object a, Object b) 先做非空判断,比较两个对象
public static boolean isNull(Object obj) 判断对象是否为null,为nul1返回true ,反之
public static boolean nonNull(Object obj) 判断对象是否为null,跟isNull的结果相反
*/
//1.创建学生类的对象
Student s1 = null;
Student s2 = new Student("zhangsan", 23);
//2.比较两个对象的属性值是否相同
if(s1 != null){
boolean result = s1.equals(s2);
System.out.println(result);
}else{
System.out.println("调用者为空");
}
boolean result = Objects.equals(s1, s2);
System.out.println(result);
//细节:
//1.方法的底层会判断s1是否为null,如果为null,直接返回false
//2.如果s1不为null,那么就利用s1再次调用equals方法
//3.此时s1是student类型,所以最终还是会调用student中的equals方法。
// 如果没有重写,比较地址值,如果重写了,就比较属性值。
//public static boolean isNull(Obiect obi) 判断对象是否为null,为nul1返回true,反之
Student s3 = new Student();
Student s4 = null;
System.out.println(Objects.isNull(s3));//false
System.out.println(Objects.isNull(s4));//true
System.out.println(Objects.nonNull(s3));//true
System.out.println(Objects.nonNull(s4));//false
}
}
BigInteger
BigInteger概述
在Java中,证书有四种类型:byte、short、int、long
在底层占用字节个数:byte1个字节,short2个字节,int4个字节,long8个字节
BigInteger构造方法
public BigInteger(int num, Random rnd) 获取随机大整数,范围:[0~ 2的num次方-1]
Random r = new Random();
for (int i = 0; i < 100; i++) {
BigInteger bi1 = new BigInteger(4, r);
System.out.println(bi1);
}
这样子就能打印出0~15的随机数
public BigInteger(String val) 获取指定的大整数 --> 括号里面需要写字符串的形式,并且该字符串的内容必须是一个整数,否则会报错
BigInteger bi2 = new BigInteger("999999999999999999");
System.out.println(bi2); // 999999999999999999
/* BigInteger bd2 = new BigInteger("1.1");
System.out.println(bd2);报错
*/
/*
BigInteger bd3 = new BigInteger("abc");
System.out.println(bd3);报错
*/
public BigInteger(String val, int radix) 获取指定进制的大整数 括号里面第一个变量也是字符串类型的,并且要符合第二个变量的要求,例如后面的数字是2,那么第一个变量只能写2进制的形式
BigInteger bi3 = new BigInteger("100", 2);
System.out.println(bi3); // 4
public static BigInteger valueOf(long val) 静态方法获取BigInteger的对象,内部有优化
由于该方法是静态方法,因此调用的时候直接用类名调用即可
并且在这个方法内部,它会先把-16~16进行内部优化,会提前给这些数字创建好BigInterger对象,这样多次获取也不会重新创建新的BigInterger对象
BigInteger bd5 = BigInteger.valueOf(16);
BigInteger bd6 = BigInteger.valueOf(16);
System.out.println(bd5 == bd6);//true
BigInteger bd7 = BigInteger.valueOf(17);
BigInteger bd8 = BigInteger.valueOf(17);
System.out.println(bd7 == bd8);//false
BigInterger对象一旦创建,内部的数据就不会发生改变,例如进行加法运算的时候,便会创建一个新的BigInterger对象接收他们的和
BigInteger bd9 =BigInteger.valueOf(1);
BigInteger bd10 =BigInteger.valueOf(2);
//此时,不会修改参与计算的BigInteger对象中的借,而是产生了一个新的BigInteger对象记录
BigInteger result=bd9.add(bd10);
System.out.println(result);//3
BigInterger常见方法
package com.itheima.bigintegerdemo;
import java.math.BigInteger;
public class BigIntegerDemo2 {
public static void main(String[] args) {
/*
public BigInteger add(BigInteger val) 加法
public BigInteger subtract(BigInteger val) 减法
public BigInteger multiply(BigInteger val) 乘法
public BigInteger divide(BigInteger val) 除法,获取商
public BigInteger[] divideAndRemainder(BigInteger val) 除法,获取商和余数
public boolean equals(Object x) 比较是否相同
public BigInteger pow(int exponent) 次幂
public BigInteger max/min(BigInteger val) 返回较大值/较小值
public int intValue(BigInteger val) 转为int类型整数,超出范围数据有误
*/
//1.创建两个BigInteger对象
BigInteger bd1 = BigInteger.valueOf(10);
BigInteger bd2 = BigInteger.valueOf(5);
//2.加法
BigInteger bd3 = bd1.add(bd2);
System.out.println(bd3);
//3.除法,获取商和余数
BigInteger[] arr = bd1.divideAndRemainder(bd2);
System.out.println(arr[0]);
System.out.println(arr[1]);
//4.比较是否相同
boolean result = bd1.equals(bd2);
System.out.println(result);
//5.次幂
BigInteger bd4 = bd1.pow(2);
System.out.println(bd4);
//6.max
// 获取的最大值并不会再创减一个新的BigInteger对象进行接收
BigInteger bd5 = bd1.max(bd2);
//7.转为int类型整数,超出范围数据有误
/* BigInteger bd6 = BigInteger.valueOf(2147483647L);
int i = bd6.intValue();
System.out.println(i);
*/
BigInteger bd6 = BigInteger.valueOf(200);
double v = bd6.doubleValue();
System.out.println(v);//200.0
int i = bd6.intValue();
System.out.println(i);
}
}
BigInterger底层存储原理
BigInterger底村存储方式
BigInterger存储上限
小结
如果BigInteger表示的数字没有超过long范围,可以用valueof()静态方法获取
如果BigInteger表示饿数字超出long范围,可以用静态方法获取
对象一旦创建,BigInteger内部记录的值不能发生改变
只要进行计算都会产生一个新的BigInteger对象
BigInterger要掌握的点
BigDecima
计算机中的小数
如果用double表示0.226便超出范围了
BigDecima的作用
- 用于小数的精确计算,解决小数运算精度失真的问题
- 用来表示很大的小数
BigDecima获取方式
/*
构造方法获取BigDecimal对象
public BigDecimal(double val) public BigDecimal(string val)
静态方法获取BigDecimal对象
public static BigDecimal valuef(double val)
*/
//1.通过传递double类型的小数来创建对象
//细节:
//这种方式有可能是不精确的,所以不建议使用
BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = new BigDecimal(0.09);
System.out.println(bd1);
System.out.println(bd2);
//通过传递字符串表示的小数来创建对象
BigDecimal bd3 = new BigDecimal("0.01");
BigDecimal bd4 = new BigDecimal("0.09");
BigDecimal bd5 = bd3.add(bd4);
System.out.println(bd3);
System.out.println(bd4);
System.out.println(bd5);
//3.通过静态方法获取对象
//细节:
//1.如果要表示的数字不大,没有超出double的取值范围,建议使用静态方法
//2.如果要表示的数字比较大,超出了double的取值范围,建议使用构造方法
//3.如果我们传递的是0~10之间的整数,包含0,包含10,那么方法会返回已经创建好的对象,不会重新new
BigDecimal bd6 = BigDecimal.valueOf(10.0);
BigDecimal bd7 = BigDecimal.valueOf(10.0);
System.out.println(bd6 == bd7);
}
BigDecima的使用
BigDecima要掌握的点
正则表达式
正则表达式的作用
作用一:校验字符串是否满足规则
作用二:在一段文本中查找满足要求的内容
正则表达式小结 
package com.itheima.regexdemo;
public class RegexDemo2 {
public static void main(String[] args) {
//public boolean matches(String regex):判断是否与正则表达式匹配,匹配返回true
// 只能是a b c
System.out.println("-----------1-------------");
System.out.println("a".matches("[abc]")); // true
System.out.println("z".matches("[abc]")); // false
// 不能出现a b c
System.out.println("-----------2-------------");
System.out.println("a".matches("[^abc]")); // false
System.out.println("z".matches("[^abc]")); // true
System.out.println("zz".matches("[^abc]")); //false
System.out.println("zz".matches("[^abc][^abc]")); //true
// a到zA到Z(包括头尾的范围)
System.out.println("-----------3-------------");
System.out.println("a".matches("[a-zA-z]")); // true
System.out.println("z".matches("[a-zA-z]")); // true
System.out.println("aa".matches("[a-zA-z]"));//false
System.out.println("zz".matches("[a-zA-Z]")); //false
System.out.println("zz".matches("[a-zA-Z][a-zA-Z]")); //true
System.out.println("0".matches("[a-zA-Z]"));//false
System.out.println("0".matches("[a-zA-Z0-9]"));//true
// [a-d[m-p]] a到d,或m到p
System.out.println("-----------4-------------");
System.out.println("a".matches("[a-d[m-p]]"));//true
System.out.println("d".matches("[a-d[m-p]]")); //true
System.out.println("m".matches("[a-d[m-p]]")); //true
System.out.println("p".matches("[a-d[m-p]]")); //true
System.out.println("e".matches("[a-d[m-p]]")); //false
System.out.println("0".matches("[a-d[m-p]]")); //false
// [a-z&&[def]] a-z和def的交集。为:d,e,f
System.out.println("----------5------------");
System.out.println("a".matches("[a-z&[def]]")); //false
System.out.println("d".matches("[a-z&&[def]]")); //true
System.out.println("0".matches("[a-z&&[def]]")); //false
// [a-z&&[^bc]] a-z和非bc的交集。(等同于[ad-z])
System.out.println("-----------6------------_");
System.out.println("a".matches("[a-z&&[^bc]]"));//true
System.out.println("b".matches("[a-z&&[^bc]]")); //false
System.out.println("0".matches("[a-z&&[^bc]]")); //false
// [a-z&&[^m-p]] a到z和除了m到p的交集。(等同于[a-1q-z])
System.out.println("-----------7-------------");
System.out.println("a".matches("[a-z&&[^m-p]]")); //true
System.out.println("m".matches("[a-z&&[^m-p]]")); //false
System.out.println("0".matches("[a-z&&[^m-p]]")); //false
}
}
package com.itheima.regexdemo;
public class RegexDemo3 {
public static void main(String[] args) {
// \ 转义字符 改变后面那个字符原本的含义
//练习:以字符串的形式打印一个双引号
//"在Java中表示字符串的开头或者结尾
//此时\表示转义字符,改变了后面那个双引号原本的含义
//把他变成了一个普普通通的双引号而已。
System.out.println("\"");
// \表示转义字符
//两个\的理解方式:前面的\是一个转义字符,改变了后面\原本的含义,把他变成一个普普通通的\而已。
System.out.println("C:\\Users\\罗弘杰\\Desktop\\源项目\\untitled\\myapi\\src\\com\\itheima\\regexdemo\\RegexDemo3.java");
//.表示任意一个字符
System.out.println("你".matches("..")); //false
System.out.println("你".matches(".")); //true
System.out.println("你a".matches(".."));//true
// \\d 表示任意的一个数字
// \\d只能是任意的一位数字
// 简单来记:两个\表示一个\
System.out.println("a".matches("\\d")); // false
System.out.println("3".matches("\\d")); // true
System.out.println("333".matches("\\d")); // false
//\\w只能是一位单词字符[a-zA-Z_0-9]
System.out.println("z".matches("\\w")); // true
System.out.println("2".matches("\\w")); // true
System.out.println("21".matches("\\w")); // false
System.out.println("你".matches("\\w"));//false
// 非单词字符
System.out.println("你".matches("\\W")); // true
System.out.println("---------------------------------------------");
// 以上正则匹配只能校验单个字符。
// 必须是数字 字母 下划线 至少 6位
System.out.println("2442fsfsf".matches("\\w{6,}"));//true
System.out.println("244f".matches("\\w{6,}"));//false
// 必须是数字和字符 必须是4位
System.out.println("23dF".matches("[a-zA-Z0-9]{4}"));//true
System.out.println("23 F".matches("[a-zA-Z0-9]{4}"));//false
System.out.println("23dF".matches("[\\w&&[^_]]{4}"));//true
System.out.println("23_F".matches("[\\w&&[^_]]{4}"));//false
}
}
package com.itheima.regexdemo;
public class RegexDemo4 {
public static void main(String[] args) {
/*
需求
请编写正则表达式验证用户输入的手机号码是否满足要求。请编写正则表达式验证用户输入的邮箱号是否满足要求。请编写正则表达式验证用户输入的电话号码是否满足要求。
验证手机号码 13112345678 13712345667 13945679027 139456790271
验证座机电话号码 020-2324242 02122442 027-42424 0712-3242434
验证邮箱号码 3232323@qq.com zhangsan@itcast.cnn dlei0009@163.com dlei0009@pci.com.cn
*/
//心得:
//拿着一个正确的数据,从左到右依次去写。
//13112345678
//分成三部分:
//第一部分:1 表示手机号码只能以1开头
//第二部分:[3-9] 表示手机号码第二位只能是3-9之间的
//第三部分:\\d{9} 表示任意数字可以出现9次,也只能出现9次
String regex1 = "1[3-9]\\d{9}";
System.out.println("13112345678".matches(regex1));//true
System.out.println("13712345667".matches(regex1));//true
System.out.println("13945679027".matches(regex1));//true
System.out.println("139456790271".matches(regex1));//false
System.out.println("-----------------------------------");
//座机电话号码
//020-2324242 02122442 027-42424 0712-3242434
//思路:
//在书写座机号正则的时候需要把正确的数据分为三部分
//一:区号@\\d{2,3}
// 0:表示区号一定是以0开头的
// \\d{2,3}:表示区号从第二位开始可以是任意的数字,可以出现2到3次。
//二:- ?表示次数,日次或一次
//三:号码 号码的第一位也不能以日开头,从第二位开始可以是任意的数字,号码的总长度:5-10位
String regex2 = "0\\d{2,3}-?[1-9]\\d{4,9}";
System.out.println("020-2324242".matches(regex2));
System.out.println("02122442".matches(regex2));
System.out.println("027-42424".matches(regex2));
System.out.println("0712-3242434".matches(regex2));
//邮箱号码
//3232323@qq.com zhangsan@itcast.cnn dlei0009@163.com dlei0009@pci.com.cn
//思路:
//在书写邮箱号码正则的时候需要把正确的数据分为三部分
//第一部分:@的左边 \\w+
// 任意的字母数字下划线,至少出现一次就可以了
//第二部分:@ 只能出现一次
//第三部分:
// 3.1 .的左边[\\w&&[^_]]{2,6}
// 任意的字母加数字,总共出现2-6次(此时不能出现下划线)
// 3.2 . \\.
// 3.3 大写字母,小写字母都可以,只能出现2-3次[a-zA-Z]{2,3}
// 我们可以把3.2和3.3看成一组,这一组可以出现1次或者两次
String regex3 = "\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}";
System.out.println("3232323@qq.com".matches(regex3));
System.out.println("zhangsan@itcast.cnn".matches(regex3));
System.out.println("dlei0009@163.com".matches(regex3));
System.out.println("dlei0009@pci.com.cn".matches(regex3));
}
}
package com.itheima.regexdemo;
import java.util.logging.XMLFormatter;
public class RegexDemo5 {
public static void main(String[] args) {
/*
正则表达式练习:
需求
请编写正则表达式验证用户名是否满足要求。要求:大小写字母,数字,下划线一共4-16位请编写正则表达式验证身份证号码是否满足要求。
简单要求:18位,前17位任意数字,最后一位可以是数字可以是大写或小写的x复杂要求:按照身份证号码的格式严格要求。
身份证号码:
41080119930228457x
510801197609022309
15040119810705387X
130133197204039024 I
430102197606046442
*/
//用户名要求:大小写字母,数字,下划线一共4-16位
String regex1 = "\\w{4,16}";
System.out.println("zhangsan".matches(regex1));
System.out.println("lisi".matches(regex1));
System.out.println("wangwu".matches(regex1));
System.out.println("$123".matches(regex1));
//身份证号码的简单校验:
//18位,前17位任意数字,最后一位可以是数字可以是大写或小写的x
String regex2 = "[1-9]\\d{16}(\\d|X|x)";
String regex3 = "[1-9]\\d{16}[\\dXx]";
String regex5 = "[1-9]\\d{16}[\\d(?i)x]";
System.out.println("41080119930228457x".matches(regex5));
System.out.println("510801197609022309".matches(regex5));
System.out.println("15040119810705387X".matches(regex5));
System.out.println("130133197204039024".matches(regex5));
System.out.println("430102197606046442".matches(regex5));
//忽略大小写的书写方式
//在匹配的时候忽略abc的大小写
String regex4 = "a((?i)b)c";
System.out.println("------------------------------");
System.out.println("abc".matches(regex4));//true
System.out.println("ABC".matches(regex4));//false
System.out.println("aBc".matches(regex4));//true
//身份证号码的严格校验
//编写正则的小心得:
//第一步:按照正确的数据进行拆分
//第二步:找每一部分的规律,并编写正则表达式
//第三步:把每一部分的正则拼接在一起,就是最终的结果
//书写的时候:从左到右去书写。
//410801 1993 02 28 457x
//前面6位:省份,市区,派出所等信息,第一位不能是0,后面5位是任意数字 [1-9]\\d{5}
//年的前半段: 18 19 20 (18|19|20)
//年的后半段: 任意数字出现两次 \\d{2}
//月份: 01~ 09 10 11 12 (@[1-9]|1[0-2])
//日期: 01~09 10~19 20~29 30 31 (0[1-9]|[12]\\d|3[01])
//后面四位: 任意数字出现3次 最后一位可以是数字也可以是大写x或者小写x \\d{3}[\\dXx]
String regex6 = "[1-9]\\d{5}(18|19|20)\\d{2}(@[1-9]|1[0-2])(@[1-9]|[12]\\d|3[01])\\d{3}[\\dxXx]";
System.out.println("41080119930228457x".matches(regex6));
System.out.println("510801197609022309".matches(regex6));
System.out.println("15040119810705387X".matches(regex6));
System.out.println("130133197204039024".matches(regex6));
System.out.println("430102197606046442".matches(regex6));
}
}
package com.itheima.regexdemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo6 {
public static void main(String[] args) {
/* 有如下文本,请按照要求爬取数据。
Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,
因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台
要求:找出里面所有的JavaXX
*/
String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
//1.获取正则表达式的对象
Pattern p = Pattern.compile("Java\\d{0,2}");
//2.获取文本匹配器的对象
//拿着m去读取str,找符合p规则的子串
Matcher m = p.matcher(str);
//3.利用循环获取
while (m.find()) {
String s = m.group();
System.out.println(s);
}
}
private static void method1(String str) {
//Pattern:表示正则表达式
//Matcher: 文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。
// 在大串中去找符合匹配规则的子串。
//获取正则表达式的对象
Pattern p = Pattern.compile("Java\\d{0,2}");
//获取文本匹配器的对象
//m:文本匹配器的对象
//str:大串
//p:规则
//m要在str中找符合p规则的小串
Matcher m = p.matcher(str);
//拿着文本匹配器从头开始读取,寻找是否有满足规则的子串
//如果没有,方法返回false
//如果有,返回true。在底层记录子串的起始索引和结束索引+1
// 0,4
boolean b = m.find();
//方法底层会根据find方法记录的索引进行字符串的截取
// substring(起始索引,结束索引);包头不包尾
// (0,4)但是不包含4索引
// 会把截取的小串进行返回。
String s1 = m.group();
System.out.println(s1);
//第二次在调用find的时候,会继续读取后面的内容
//读取到第二个满足要求的子串,方法会继续返回true
//并把第二个子串的起始索引和结束索引+1,进行记录
b = m.find();
//第二次调用group方法的时候,会根据find方法记录的索引再次截取子串
String s2 = m.group();
System.out.println(s2);
}
}
package com.itheima.regexdemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo8 {
public static void main(String[] args) {
/*
需求:把下面文本中的座机电话,邮箱,手机号,热线都爬取出来。
来黑马程序员学习Java,
手机号:18512516758,18512508907或者联系邮箱:boniu@itcast.cn,
座机电话:01036517895,010-98951256邮箱:bozai@itcast.cn,
热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090
手机号的正则表达式:1[3-9]\d{9}
邮箱的正则表达式:\w+@[\w&&[^_]]{2,6}(\.[a-zA-Z]{2,3}){1,2}座机电话的正则表达式:θ\d{2,3}-?[1-9]\d{4,9}
热线电话的正则表达式:400-?[1-9]\\d{2}-?[1-9]\\d{3}
*/
String s = "来黑马程序员学习Java," +
"电话:18512516758,18512508907" + "或者联系邮箱:boniu@itcast.cn," +
"座机电话:01036517895,010-98951256" + "邮箱:bozai@itcast.cn," +
"热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090";
System.out.println("400-618-9090");
String regex = "(1[3-9]\\d{9})|(\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2})" +
"|(0\\d{2,3}-?[1-9]\\d{4,9})" +
"|(400-?[1-9]\\d{2}-?[1-9]\\d{3})";
//1.获取正则表达式的对象
Pattern p = Pattern.compile(regex);
//2.获取文本匹配器的对象
//利用m去读取s,会按照p的规则找里面的小串
Matcher m = p.matcher(s);
//3.利用循环获取每一个数据
while(m.find()) {
String str = m.group();
System.out.println(str);
}
}
}
package com.itheima.regexdemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo9 {
public static void main(String[] args) {
/*
有如下文本,按要求爬取数据。
Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,
因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台
需求1:爬取版本号为8,11.17的Java文本,但是只要Java,不显示版本号。
需求2:爬取版本号为8,11,17的Java文本。正确爬取结果为:Java8 Java11 Java17 Java17
需求3:爬取除了版本号为8,11.17的Java文本,
*/
String s = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和JAva11," +
"因为这两个是长期支持版本,下一个长期支持版本是java17,相信在未来不久JAVA17也会逐渐登上历史舞台";
//1.定义正则表达式
//?理解为前面的数据Java
//=表示在Java后面要跟随的数据
//但是在获取的时候,只获取前半部分
//需求1:
String regex1 = "((?i)Java)(?=8|11|17)";
//需求2:
String regex2 = "((?i)Java)(8|11|17)";
String regex3 = "((?i)Java)(?:8|11|17)";
//需求3:
String regex4 = "((?i)Java)(?!8|11|17)";
Pattern p = Pattern.compile(regex4);
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());
}
}
}
package com.itheima.regexdemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo10 {
public static void main(String[] args) {
/*
只写+和*表示贪婪匹配
+? 非贪婪匹配
*? 非贪婪匹配
贪婪爬取:在爬取数据的时候尽可能的多获取数据
非贪婪爬取:在爬取数据的时候尽可能的少获取数据
ab+:
贪婪爬取:abbbbbbbbbbbb
非贪婪爬取:ab
*/
String s = "Java自从95年问世以来,abbbbbbbbbbbbaaaaaaaaaaaaaaaaaa" +
"经历了很多版木,目前企业中用的最多的是]ava8和]ava11,因为这两个是长期支持版木。" +
"下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
String regex = "ab+";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());
}
String regex1 = "ab+?";
Pattern p1 = Pattern.compile(regex1);
Matcher m1 = p1.matcher(s);
while (m1.find()) {
System.out.println(m1.group());
}
}
}
正则表达式在字符串中的使用
package com.itheima.regexdemo;
public class RegexDemo11 {
public static void main(String[] args) {
//public string replaceAll(string regex,string newstr) 按照正则表达式的规则进行替换
//public string[] split(string regex): 按照正则表达式的规则切割字符串
/*
有一段字符串:小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠
要求1:把字符串中三个姓名之间的字母替换为vs
要求2:把字符串中的三个姓名切割出来*/
String s = "小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠";
//细节:
//方法在底层跟之前一样也会创建文本解析器的对象
//然后从头开始去读取字符串中的内容,只要有满足的,那么就用第一个参数去替换。
String result1 = s.replaceAll("[\\w&&[^_]]+", "vs");
System.out.println(result1);
String[] arr = s.split("[\\w&&[^_]]+");
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
分组
package com.itheima.regexdemo;
public class RegexDemo12 {
public static void main(String[] args) {
//需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
//举例: a123a b456b 17891 &abc& a123b(false)
// \\组号:表示把第X组的内容再出来用一次
String regex1 = "(.).+\\1";
System.out.println("a123a".matches(regex1));
System.out.println("b456b".matches(regex1));
System.out.println("17891".matches(regex1));
System.out.println("&abc&".matches(regex1));
System.out.println("a123b".matches(regex1));
System.out.println("--------------------------");
//需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
//举例: abc123abc b456b 123789123 &!@abc&!@ abc123abd(false)
String regex2 = "(.+).+\\1";
System.out.println("abc123abc".matches(regex2));
System.out.println("b456b".matches(regex2));
System.out.println("123789123".matches(regex2));
System.out.println("&!@abc&!@".matches(regex2));
System.out.println("abc123abd".matches(regex2));
System.out.println("---------------------");
//需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致
//举例: aaa123aaa bbb456bbb 111789111 &&abc&&
//(.):把首字母看做一组
// \\2:把首字母拿出来再次使用
// *:作用于\\2,表示后面重复的内容出现日次或多次
String regex3 = "((.)\\2*).+\\1";
System.out.println("aaa123aaa".matches(regex3));
System.out.println("bbb456bbb".matches(regex3));
System.out.println("111789111".matches(regex3));
System.out.println("&&abc&&".matches(regex3));
System.out.println("aaa123aab".matches(regex3));
}
}
package com.itheima.regexdemo;
public class RegexDemo13 {
public static void main(String[] args) {
/*需求:
将字符串:我要学学编编编编程程程程程程替换为:我要学编程
*/
String str = "我要学学编编编编程程程程程程";
//需求:把重复的内容 替换为 单个的
//学学 学
//编编编编 编
//程程程程程程 程
// (.)表示把重复内容的第一个字符看做一组
// \\1表示第一字符再次出现
// + 至少一次
// $1 表示把正则表达式中第一组的内容,再拿出来用
String result = str.replaceAll("(.)\\1+", "$1");
System.out.println(result);
}
}
捕获分组和非捕获分组
package com.itheima.regexdemo;
public class RegexDemo14 {
public static void main(String[] args) {
/*
非捕获分组:分组之后不需要再用本组数据,仅仅是把数据括起来。
身份证号码:
41080119930228457x51080119760902230915040119810705387X130133197204039024430102197606046442
*/
//身份证号码的简易正则表达式
//非捕获分组:仅仅是把数据括起来//特点:不占用组号
//这里\\1报错原因:(?:)就是非捕获分组,此时是不占用组号的。
//(?:) (?=) (?!)都是非捕获分组//更多的使用第一个
//String regex1 ="[1-9]\\d{16}(?:\\d|x|x)\\1";
String regex2 ="[1-9]\\d{16}(\\d Xx)\\1";
//^([01]\d|2[0-3]):[0-5]\d:[@-5]\d$
System.out.println("41080119930228457x".matches(regex2));
}
}
总结
JDK7以前时间相关类
Date时间类
package com.itheima.datedemo;
import java.util.Date;
public class DateDemo1 {
public static void main(String[] args) {
// 当前时间
Date d = new Date();
System.out.println(d);
// 指定时间
Date d1 = new Date(0L);
System.out.println(d1);
// 修改时间
d1.setTime(1000L);
System.out.println(d1);
// 获取当前事件的毫秒值
System.out.println(d1.getTime());
}
}
运行结果:
时间计算
package com.itheima.datedemo;
import java.util.Date;
import java.util.Random;
public class DateDemo2 {
public static void main(String[] args) {
long time = 0;
time = time + 1000L * 60 * 60 * 24 * 365;
Date d1 = new Date(time);
System.out.println(d1);
Random r = new Random();
Date d2 = new Date(r.nextLong());
Date d3 = new Date(r.nextLong());
long time1 = d2.getTime();
long time2 = d3.getTime();
if (time1 > time2) {
System.out.println("第一个在后");
} else if (time1 < time2) {
System.out.println("第二个在后");
} else {
System.out.println("一样");
}
}
}
SimpleDataFormat类
SimpleDataFormat类作用
格式化:把时间变成我们想要的格式
解析:将字符串表示的时间变成Date对象
package com.itheima.simpledateformat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatDemo1 {
public static void main(String[] args) throws ParseException {
// 1. 默认的格式化
Date d1 = new Date();
SimpleDateFormat sdf1 = new SimpleDateFormat();
String format = sdf1.format(d1);
System.out.println(format);
// 2. 指定的格式化
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf2.format(d1));
// 3. 解析
String s = "2024-09-30 11:23:30";
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d2 = sdf3.parse(s);
System.out.println(d2.getTime());
}
}
按照指定格式展示
package com.itheima.simpledateformat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatDemo2 {
public static void main(String[] args) throws ParseException {
String str1 = "2000-11-11";
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
Date d1 = sdf1.parse(str1);
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");
System.out.println(sdf2.format(d1));
}
}
秒杀活动
package com.itheima.simpledateformat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatDemo3 {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String start = "2023年11月11日 00:00:00";
String end = "2023年11月11日 00:10:00";
String s1 = "2023年11月11日 00:01:00";
String s2 = "2023年11月11日 00:11:00";
Date startdate = sdf1.parse(start);
Date enddate = sdf1.parse(end);
Date date1 = sdf1.parse(s1);
Date date2 = sdf1.parse(s2);
long time = enddate.getTime() - startdate.getTime();
if ((date1.getTime() - startdate.getTime()) > time) {
System.out.println("小贾没抢到");
} else {
System.out.println("小贾抢到了");
}
if ((date2.getTime() - startdate.getTime()) > time) {
System.out.println("小皮没抢到");
} else {
System.out.println("小皮抢到了");
}
}
}
Calendar类
Calendar概述
Calendar代表了系统当前时间的日历对象,可以单独修改、获取时间中的年、月、日
Calendar是一个抽象类,不能直接创建对象
获取Calendar对象的方法
Calendar常用方法
package com.itheima.calendardemo;
import java.util.Calendar;
import java.util.Date;
public class CalendarDemo1 {
public static void main(String[] args) {
// 1. 获取日历对象
Calendar c = Calendar.getInstance();
// 2. 创建一个日期对象
Date d = new Date();
// 3. 给日历对象设置日期对象
c.setTime(d);
// 单独修改年份信息
c.set(Calendar.YEAR, 2000);
// 单独修改月份信息
c.set(Calendar.MONTH, 4);
// 单独修改日期信息
c.set(Calendar.DATE, 8);
// 增加日期
c.add(Calendar.DATE,10);
// 4. 获取日历中的年信息
int year = c.get(Calendar.YEAR);
// 5. 获取日历中的月信息
int month = c.get(Calendar.MONTH) + 1;
// 6. 获取日历中的日信息
int date = c.get(Calendar.DATE);
// 7. 获取日历中的星期信息
int week = c.get(Calendar.DAY_OF_WEEK) - 1;
// 打印日期
System.out.println(year + "," + month + "," + date + "," + getWeek(week));
}
public static String getWeek(int index){
// 定义一个字符数组,与Calendar返回的数据一一对应
String[] arr = {"", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
// 返回对应的数据
return arr[index];
}
}
有一点需要注意的就是,即使你设定的月份很大,程序也不会报错,而是给你自动计算加在年份上面。(日期同理)
月份获取到的是(0~11),因此要获取准确的月份需要自行加一
星期获取到的是(1~7),但是1对应的是星期日
月份和星期若是想获取准确的日期,可以使用查表法,在定义一个方法,再方法内部定义与索引一一对应的字符数组,返回对应的值即可。
JDK8新增时间相关类
为什么要学习JDK8新增时间相关类
JDK8时间
ZoneId类
package com.itheima.jdk8timedemo;
import java.time.ZoneId;
import java.util.Set;
public class ZoneIdDemo {
public static void main(String[] args) {
// 获取所有时区的集合
Set<String> zoneIds = ZoneId.getAvailableZoneIds();
System.out.println(zoneIds);
// 获取系统当前的时区
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId);
// 指定当前的时区
ZoneId id = ZoneId.of("Asia/Shanghai");
System.out.println(id);
}
}
Instant类
package com.itheima.jdk8timedemo;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class InstantDemo {
public static void main(String[] args) {
// 获取当前的世界标准时间,带纳秒的
Instant now = Instant.now();
System.out.println(now);
// 根据设置的毫秒获取Instant对象
Instant milli = Instant.ofEpochMilli(0L);
System.out.println(milli);
// 指定时区,获得该时区的时间并带有时区
ZonedDateTime zone = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zone);
// isBefore isAfter 判断系列的方法
Instant instant1 = Instant.ofEpochSecond(100L);
Instant instant2 = Instant.ofEpochSecond(200L);
boolean b = instant1.isBefore(instant2);
System.out.println(b);
// 减少时间系列的方法
Instant instant3 = instant1.minusMillis(20L);
System.out.println(instant1);
System.out.println(instant3);
// 增加时间系列的方法
Instant instant4 = instant2.plusMillis(20L);
System.out.println(instant2);
System.out.println(instant4);
}
}
ZoneDateTime类
package com.itheima.jdk8timedemo;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class ZoneDateTimeDemo {
public static void main(String[] args) {
// 获取当前的ZonedDateTime对象,输出包含时区
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now);
// 获取指定时间的ZonedDateTime对象
ZonedDateTime time = ZonedDateTime.of(2000, 9, 8, 21, 15, 42, 66666, ZoneId.of("Asia/Shanghai"));
System.out.println(time);
// 修改时间系列的方法
ZonedDateTime time1 = time.withHour(15);
System.out.println(time1);
// 减少时间系列
ZonedDateTime time2 = time.minusHours(3L);
System.out.println(time2);
// 增加时间系列
ZonedDateTime time3 = time.plusHours(2L);
System.out.println(time3);
}
}
DateTimeFormatter类
package com.itheima.jdk8timedemo;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class DateTimeFormatterDemo {
public static void main(String[] args) {
ZonedDateTime now = ZonedDateTime.now();
// 换成具体的格式
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EE a");
String s = dateTimeFormatter.format(now);
System.out.println(s);
}
}
LocalDate、LocalTime、LocalDateTime
LocalDate
package com.itheima.jdk8timedemo;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
public class LocalDateDemo {
public static void main(String[] args) {
// 获取当前的年月日
LocalDate now = LocalDate.now(); // 2024-10-08
System.out.println(now);
// 指定当前的年月日
LocalDate l1 = LocalDate.of(2003,9,8);
System.out.println(l1);
// 修改其中的信息
LocalDate l2 = l1.withMonth(5);
System.out.println(l2);
// 获取当前的年信息
int year = now.getYear();
System.out.println(year);
// 获取当前的月信息
Month month = now.getMonth();
System.out.println(month); // OCTOBER
System.out.println(month.getValue()); // 10
// 获取当前的日信息
int date = now.getDayOfMonth();
System.out.println(date);
// 获取当前的星期
DayOfWeek week = now.getDayOfWeek();
System.out.println(week); // TUESDAY
System.out.println(week.getValue()); // 2
// 增加某一信息
LocalDate plusYears = now.plusYears(2);
System.out.println(plusYears); // 2026-10-08
// 减少某一信息
LocalDate minusMonths = now.minusMonths(2);
System.out.println(minusMonths); // 2024-08-08
}
}
LocalTime
package com.itheima.jdk8timedemo;
import java.time.LocalTime;
public class LocalTimeDemo {
public static void main(String[] args) {
// 获取当前时间的时分秒
LocalTime now = LocalTime.now();
System.out.println(now);
// 指定时间的时分秒
LocalTime t1 = LocalTime.of(20,0,0);
System.out.println(t1);
// 获取时间的时
int hour = t1.getHour();
System.out.println(hour);
// 获取时间的分
int minute = t1.getMinute();
System.out.println(minute);
// 获取时间的秒
int second = t1.getSecond();
System.out.println(second);
// 获取时间的纳秒
int nano = t1.getNano();
System.out.println(nano);
// 修改时间的时
LocalTime t2 = t1.withHour(21);
System.out.println(t2);
// 增加时间的分
LocalTime plusMinutes = t1.plusMinutes(20);
System.out.println(plusMinutes);
// 减少时间的秒
LocalTime minusSeconds = t1.minusSeconds(20);
System.out.println(minusSeconds);
}
}
LocalDateTime
package com.itheima.jdk8timedemo;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class LocalDateTimeDemo {
public static void main(String[] args) {
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
// 获取当前时间的一系列信息
System.out.println(now.getYear());
System.out.println(now.getMonth());
System.out.println(now.getMonthValue());
System.out.println(now.getDayOfMonth());
System.out.println(now.getDayOfWeek());
System.out.println(now.getDayOfWeek().getValue());
System.out.println(now.getHour());
System.out.println(now.getMinute());
System.out.println(now.getSecond());
// 转换类型
// LocalDate
LocalDate nowLocalDate = now.toLocalDate();
System.out.println(nowLocalDate);
// LocalTime
LocalTime nowLocalTime = now.toLocalTime();
System.out.println(nowLocalTime);
}
}
Duration、Period、ChronoUnit
Duration
package com.itheima.jdk8timedemo;
import java.time.Duration;
import java.time.LocalDateTime;
public class DurationDemo {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime birthday = LocalDateTime.of(2003,9,8,21,0,0);
Duration duration = Duration.between(birthday, now);
System.out.println(duration); // PT184818H4M11.9659204S
System.out.println(duration.toDays());
System.out.println(duration.toHours());
System.out.println(duration.toMinutes());
System.out.println(duration.toSeconds());
System.out.println(duration.toNanos());
}
}
Period
package com.itheima.jdk8timedemo;
import java.time.LocalDate;
import java.time.Period;
public class PeriodDemo {
public static void main(String[] args) {
LocalDate now = LocalDate.now();
LocalDate birthday = LocalDate.of(2003,9,8);
Period period = Period.between(birthday, now);
System.out.println(period); // P21Y1M
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());
System.out.println(period.toTotalMonths());
}
}
ChronoUnit
package com.itheima.jdk8timedemo;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
public class ChronoUnitDemo {
public static void main(String[] args) {
LocalDateTime today = LocalDateTime.now();
LocalDateTime birthDate = LocalDateTime.of(2003,9,8,21,0,0);
System.out.println("相差的年数:" + ChronoUnit.YEARS.between(birthDate, today));
System.out.println("相差的月数:" + ChronoUnit.MONTHS.between(birthDate, today));
System.out.println("相差的周数:" + ChronoUnit.WEEKS.between(birthDate, today));
System.out.println("相差的天数:" + ChronoUnit.DAYS.between(birthDate, today));
System.out.println("相差的时数:" + ChronoUnit.HOURS.between(birthDate, today));
System.out.println("相差的分数:" + ChronoUnit.MINUTES.between(birthDate, today));
System.out.println("相差的秒数:" + ChronoUnit.SECONDS.between(birthDate, today));
System.out.println("相差的毫秒数:" + ChronoUnit.MILLIS.between(birthDate, today));
System.out.println("相差的微秒数:" + ChronoUnit.MICROS.between(birthDate, today));
System.out.println("相差的纳秒数:" + ChronoUnit.NANOS.between(birthDate, today));
System.out.println("相差的半天数:" + ChronoUnit.HALF_DAYS.between(birthDate, today));
System.out.println("相差的十年数:" + ChronoUnit.DECADES.between(birthDate, today));
System.out.println("相差的世纪(百年)数:" + ChronoUnit.CENTURIES.between(birthDate, today));
System.out.println("相差的千年数:" + ChronoUnit.MILLENNIA.between(birthDate, today));
System.out.println("相差的纪元数:" + ChronoUnit.ERAS.between(birthDate, today));
}
}
包装类
包装类概述
package com.itheima.integerdemo;
public class IntegerDemo1 {
public static void main(String[] args) {
/*
public Integer(int value) 根据传递的整数创建一个Integer对象
public Integer(String s) 根据传递的字符串创建一个Integer对象
public static Integer valueOf(int i) 根据传递的整数创建一个Integer对象
public static Integer valueof(String s) 根据传递的字符串创建一个Integer对象
public static Integer valueof(String s, int radix) 根据传递的字符串和进制创建一个Integer对象
*/
//1.利用构造方法获取Integer的对象(JDK5以前的方式)
/*Integer i1 = new Integer(1);
Integer i2 = new Integer("1");
System.out.println(i1);
System.out.println(i2);*/
//2.利用静态方法获取Integer的对象(JDK5以前的方式)
Integer i3 = Integer.valueOf(123);
Integer i4 = Integer.valueOf("123");
Integer i5 = Integer.valueOf("123", 8);
System.out.println(i3);
System.out.println(i4);
System.out.println(i5);
//3.这两种方式获取对象的区别(掌握)
//底层原理:
//因为在实际开发中,-128~127之间的数据,用的比较多。
//如果每次使用都是new对象,那么太浪费内存了
//所以,提前把这个范围之内的每一个数据都创建好对象
//如果要用到了不会创建新的,而是返回已经创建好的对象。
Integer i6 = Integer.valueOf(127);
Integer i7 = Integer.valueOf(127);
System.out.println(i6 == i7);//true
Integer i8 = Integer.valueOf(128);
Integer i9 = Integer.valueOf(128);
System.out.println(i8 == i9);//false
//因为看到了new关键字,在Java中,每一次new都是创建了一个新的对象
//所以下面的两个对象都是new出来,地址值不一样。
/*Integer i10 = new Integer(127);
Integer i11 = new Integer(127);
System.out.println(i10 == i11);
Integer i12 = new Integer(128);
Integer i13 = new Integer(128);
System.out.println(i12 == i13);*/
}
}
JDK5之前
package com.itheima.integerdemo;
public class IntegerDemo2 {
public static void main(String[] args) {
//在以前包装类如何进行计算
Integer i1 = new Integer(1);
Integer i2 = new Integer(2);
//需求:要把两个数据进行相加得到结果3
//对象之间是不能直接进行计算的。
//步骤:
//1.把对象进行拆箱,变成基本数据类型
//2.相加
//3.把得到的结果再次进行装箱(再变回包装类)
int result = i1.intValue() + i2.intValue();
Integer i3 = new Integer(result);
System.out.println(i3);
}
}
JDK5以后对包装类新增了自动装箱和自动拆箱的特性
package com.itheima.integerdemo;
public class IntegerDemo3 {
public static void main(String[] args) {
//在JDK5的时候提出了一个机制:自动装箱和自动拆箱
//自动装箱:把基本数据类型会自动的变成其对应的包装类
//自动拆箱:把包装类自动的变成其对象的基本数据类型
//在底层,此时还会去自动调用静态方法valueof得到一个Integer对象,只不过这个动作不需要我们自己去操作了
//自动装箱的动作
//Integer i1 = 10;
//Integer i2 = new Integer(10);
//自动拆箱的动作
//int i = i2;
//结论:在JDK5以后,int和Integer可以看做是同一个东西,因为在内部可以自动转化。
}
}
Integer成员方法
package com.itheima.integerdemo;
public class IntegerDemo4 {
public static void main(String[] args) {
/*
public static string tobinarystring(int i) 得到二进制
public static string tooctalstring(int i) 得到八进制
public static string toHexstring(int i) 得到十六进制
public static int parseInt(string s) 将字符串类型的整数转成int类型的整数
*/
//1.把整数转成二进制,十六进制
String str1 = Integer.toBinaryString(100);
System.out.println(str1);//1100100
//2.把整数转成八进制
String str2 = Integer.toOctalString(100);
System.out.println(str2);//144
//3.把整数转成十六进制
String str3 = Integer.toHexString(100);
System.out.println(str3);//64
//4.将字符串类型的整数转成int类型的整数
//强类型语言:每种数据在java中都有各自的数据类型
//在计算的时候,如果不是同一种数据类型,是无法直接计算的。
int i = Integer.parseInt("123");
System.out.println(i);
System.out.println(i + 1);//124
//细节1:
//在类型转换的时候,括号中的参数只能是数字不能是其他,否则代码会报错
//细节2:
//8种包装类当中,除了Character都有对应的parseXxx的方法,进行类型转换
String str = "true";
boolean b = Boolean.parseBoolean(str);
System.out.println(b);
}
}
键盘录入的转换
package com.itheima.integerdemo;
import java.util.Scanner;
public class IntegerDemo5 {
public static void main(String[] args) {
//键盘录入
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
/* String str = sc.next();
System.out.println(str);*/
//弊端:
//当我们在使用next,nextInt,nextDouble在接收数据的时候,遇到空格,回车,制表符的时候就停止了
//键盘录入的是123 123 那么此时只能接收到空格前面的数据
//我想要的是接收一整行数据
//约定:
//以后我们如果想要键盘录入,不管什么类型,统一使用nextLine
//特点:遇到回车才停止
String line = sc.nextLine();
System.out.println(line);
double v = Double.parseDouble(line);
System.out.println(v);
}
}
练习
package com.itheima.test;
import java.util.ArrayList;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Scanner sc = new Scanner(System.in);
// int sum = 0;
while (true) {
System.out.println("请输入一个1~100的整数:");
String line = sc.nextLine();
int num = Integer.parseInt(line);
if (num < 1 || num > 100) {
System.out.println("输入的数据有误");
continue;
}
list.add(num);
// sum = sum + num;
int sum = getSum(list);
if (sum > 200) {
System.out.println("集合中的数据超过200");
break;
}
}
}
private static int getSum(ArrayList<Integer> list) {
int sum = 0;
for (int i = 0; i < list.size(); i++) {
sum = sum + list.get(i);
}
return sum;
}
}
package com.itheima.test;
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
String regex = "[^0]\\d{0,9}";
Scanner sc = new Scanner(System.in);
System.out.println("请输入一组数据:");
String line = sc.nextLine();
boolean matches = line.matches(regex);
System.out.println(matches);
// 利用parseInt
if (matches) {
int i = Integer.parseInt(line);
System.out.println(i + 1);
}
// 实现parseInt
int number = 0;
for (int i = 0; i < line.length(); i++) {
int num = line.charAt(i) - '0';
number = number * 10 + num;
}
System.out.println(number + 1);
}
}
package com.itheima.test;
import java.util.Scanner;
public class Test3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
// 利用Java中的进制转换
System.out.println(Integer.toBinaryString(Integer.parseInt(line)));
// 实现进制转换
String s = getBinaryString(line);
System.out.println(s);
}
private static String getBinaryString(String line) {
int num = Integer.parseInt(line);
StringBuilder sb = new StringBuilder();
while (true) {
if (num != 0) {
int remainder = num % 2;
num = num / 2;
sb.insert(0, remainder);
} else {
break;
}
}
return sb.toString();
}
}
package com.itheima.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Date;
public class Test4 {
public static void main(String[] args) throws ParseException {
// JDK7
String birthday = "2003年9月8日";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
Date d1 = sdf.parse(birthday);
long d1Time = d1.getTime();
long l = System.currentTimeMillis();
long time = l - d1Time;
System.out.println(time / 1000 / 60 / 60 / 24);
// JDK8
LocalDate l1 = LocalDate.of(2003,9,8);
LocalDate l2 = LocalDate.now();
long between = ChronoUnit.DAYS.between(l1, l2);
System.out.println(between);
}
}
package com.itheima.test;
import java.time.LocalDate;
import java.util.Calendar;
public class Test5 {
public static void main(String[] args) {
// JDK7判断闰年的方法,判断2月份是否是29天
Calendar c = Calendar.getInstance();
c.set(2000, 2,1);
c.add(Calendar.DAY_OF_MONTH, -1);
System.out.println(c.get(Calendar.DAY_OF_MONTH));
// JDK8判断闰年的方法
LocalDate l = LocalDate.of(2000,3,1);
// 直接判断是否是闰年
boolean leapYear = l.isLeapYear();
// 间接判断
LocalDate l1 = l.minusDays(1);
int day = l1.getDayOfMonth();
System.out.println(day);
}
}