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)** |
System
System也是一个工具类,提供了一些与系统相关的方法
System类的常用方法:
方法名 | 说明 |
---|---|
public static void exit(int status) | 终止当前运行的Java虚拟机 |
public static long currentTimeMillis() | 返回当前系统的时间毫秒值形式 |
public static void arraycopy(数据源数组, 起始索引, 目的地数组, 起始索引, 拷贝个数) | 数组拷贝 |
时间原点:1970年1月1日00:00:00,我国在东八区,有8小时时差,因此我们操作系统的时间原点是1970年1月1日08:00:00
arraycopy细节:
① 如果数据源数组和目的地数组都是基本数据类型,那么两者的类型必须保持一致,否则会报错
② 在拷贝的时候需要考虑数组的长度,如果超出范围也会报错
③ 如果数据源数组和目的地数组都是引用数据类型,那么子类类型可以赋值给父类类型
Runtime
Runtime表示当前虚拟机的运行环境
Runtime类的常用方法:
方法名 | 说明 |
---|---|
public static Runtime getRuntime() | 返回当前系统的运行环境对象 |
public void exit(int status) | 停止虚拟机 |
public int availableProcessors() | 获得CPU的线程数 |
public long maxMemory() | JVM能从系统中获取总内存大小(单位byte) |
public long totalMemory() | JVM已经从系统中获取总内存大小(单位byte) |
public long freeMemory() | JVM剩余内存大小(单位byte) |
public Process exec(String command) | 运行cmd命令 |
注意:Runtime无法直接创建对象,因为其构造方法是私有权限的,需要通过getRuntime()
来获取对象
Object
Object是Java中的顶级父类。所有的类都直接或间接地继承于Object类
Object类中的方法可以被所有子类访问
Object的构造方法:
方法名 | 说明 |
---|---|
public Object() | 空参构造 |
Object的常用成员方法:
方法名 | 说明 |
---|---|
public String toString() | 返回对象的字符串表示形式 |
public boolean equals(Object obj) | 比较两个对象是否相等 |
protected Object clone(int a) | 对象克隆 |
toString方法的结论:如果我们打印一个对象,想要看到属性值的话,那么就重写toString方法。(因为默认的toString方法实际上是打印地址值的)
equals方法的结论:如果没有重写equals方法,那么默认使用Object中的方法进行比较,比较的是地址值是否相等。若我们需要比较属性值是否相等,就要重写equals方法
对象克隆:
把A对象的属性值完全拷贝给B对象,也叫对象拷贝,对象赋值
浅克隆:不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来
深克隆:基本数据类型拷贝过来,字符串复用,引用数据类型会重新创建新的
clone方法默认是浅克隆
书写细节:
① 重写Object中的clone方法(因为修饰符权限是protected,无法通过创建子类对象来调用)
② 让javabean类实现Cloneable接口
③ 创建原对象并调用clone就可以了
如果需要深克隆需要重写方法或者使用第三方工具类
Objects:
Objects是一个工具类,提供了一些方法去完成一些功能
Objects的成员方法:
方法名 | 说明 |
---|---|
public static boolean equals(Object a, Object b) | 先做非空判断,比较两个对象 |
public static boolean isNull(Object obj) | 判断对象是否为null,为null返回true |
public static boolean nonNull(Object obj) | 判断对象是否为null,跟isNull结果相反 |
equals方法细节:
① 若a, b不全为null,方法的底层会判断a是否为null,如果为null,直接返回false
② 如果a不为null,那么就会调用a的equals方法
③ 如果a是Student类型,那么最终还是会调用Student中的equals方法(如果没有重写,比较地址值;如果重写了,就比较属性值)
BigInterer
BigInterger获取对象方法:
方法名 | 说明 |
---|---|
public BigInteger(int num, Random rnd) | 获取随机大整数,范围:[0 ~ 2的num次方-1] |
public BigInteger(String val) | 获取指定的大整数 |
public BigInteger(String val, int radix) | 获取指定进制的大整数 |
public static BigInteger valueOf(long val) | 静态方法获取BigInteger的对象,内部有优化 |
细节:对象一旦创建,内部记录的值**不能发生改变,**只要进行计算就会产生一个新的BigInteger对象
建议:数字不超过long范围时使用静态方法获取对象;而超过long范围时使用第二个构造方法
静态方法获取对象细节:
① 能表示范围比较小,只能在long的取值范围之内,如果超出long的范围就不行了
② 在内部对常用的数字:-16~16进行了优化,提前把这些数字先创建好了BigInteger的对象,如果多次获取不会重新创建新的
BigInteger常见成员方法:
方法名 | 说明 |
---|---|
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类型整数,超出范围数据有误 |
BigDecimal
作用:
① 解决小数运算精度失真问题
② 用来表示很大的小数
BigInterger获取对象方法:
方法名 | 说明 |
---|---|
public BigDecimal(double val) | 通过double类型的小数来获取对象 |
public BigDecimal(String val) | 通过字符串表示的小数来获取对象 |
public static BigDecimal valueOf(double val) | 静态方法获取对象,内部有优化 |
第一个构造方法的细节:这种方式可能是不精确的,所以不建议使用
建议:如果要表示的数字不大,没有超出double的取值范围,建议使用静态方法;如果超出了double的取值范围,建议使用构造方法
静态方法获取对象细节:如果传递的是0~10之间的整数,包含0,包含10,那么方法会返回已经创建好的对象,不会重新new
BigDecimal常见成员方法:
方法名 | 说明 |
---|---|
public BigDecimal add(BigDecimal val) | 加法 |
public BigDecimal subtract(BigDecimal val) | 减法 |
public BigDecimal multiply(BigDecimal val) | 乘法 |
public BigDecimal divide(BigDecimal val) | 除法 |
public BigDecimal divide(BigDecimal val, 精确几位, 舍入模式) | 除法 |
正则表达式
正则表达式可以校验字符串是否满足一定的规则,并用来校验数据格式的合法性
正则表达式的作用:
① 校验字符串是否满足规则
② 在一段文本中查找满足要求的内容
字符类(只匹配一个字符):
[abc] //只能是a,b或c
[^abc] //除了a,b,c之外的任何字符
[a-zA-z] //a到z A到Z,包括头尾的范围
[a-d[m-p]] //a到d,或m到p
[a-z&&[def]] //a-z和def的交集。为:d,e,f
[a-z&&[^bc]] //a-z和非bc的交集(等同于[ad-z])
[a-z&&[^m-p]] //a到z和除了m到p的交集(等同于[a-lq-z])
预定义字符(只匹配一个字符):
. //任何字符
\d //一个数字:[0-9]
\D //非数字:[^0-9]
\s //一个空白字符:[\t\n\x0B\f\r]
\S //非空白字符:[^\s]
\w //[a-zA-Z_0-9]:英文、数字、下划线
\W //[^\w]:一个非单词字符
数量词:
X? //X,一次或0次
X* //X,零次或多次
X+ //X,一次或多次
X{n} //X,正好n次
X{n,} //X,至少n次
X{n,m} //X,至少n但不超过m次
正则表达式小结:
符号 | 含义 | 举例 |
---|---|---|
[] | 里面的内容出现一次 | [0-9] [a-zA-Z0-9] |
() | 分组 | a(bc)+ |
^ | 取反 | [^abc] |
&& | 交集,不能写单个的& | [a-z&&m-p] |
| | 写在方括号外面表示并集 | (a-zA-Z0-9) x|X |
. | 任意字符 | \n回车符号不匹配 |
\ | 转义字符 | \\d |
\\d | 0-9 | \\d+ |
\\D | 非0-9 | \\D+ |
\\s | 空白字符 | [\t\n\x0B\f\r] |
\\S | 非空白字符 | [^\s] |
\\w | 单词字符 | [a-zA-Z_0-9] |
\\W | 非单词字符 | [^\w] |
? | 0次或1次 | \\d? |
* | 0次或多次 | \\d* (abc)* |
+ | 1次或多次 | \\d+ (abc)+ |
{} | 具体次数 | a{7} \\d{7,19} |
(?i) | 忽略后面字符的大小写 | (?i)abc |
a((?i)b)c | 只忽略b的大小写 | a((?i)b)c |
练习:爬虫
//Pattern:表示正则表达式
//Matcher:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取
//获取正则表达式的对象
Pattern p = Pattern.compile(regex); // regex为正则表达式
//获取文本匹配器的对象,m要在str中找符合p规则的小串
Matcher m = p.matcher(str);
//利用循环获取
while(m.find()) {
String s = m.group();
System.out.println(s);
}
带条件爬取:
需求1:爬取版本号为8,11,17的Java文本,但是只要Java,不显示版本号
String regex1 = "Java(?=8|11|17)";
需求2:爬取版本号为8,11,17的Java文本。正确爬取结果为:Java8 Java11 Java17
String regex2 = "Java(?:8|11|17)";
需求3:爬取除了版本号为8,11,17的Java文本
String regex3 = "Java(?!8|11|17)";
贪婪爬取:在爬取数据的时候尽可能的多获取数据(Java默认)
非贪婪爬取:在爬取数据的时候尽可能的少获取数据
在数量词+
和*
的后面加上问号,那么此时就是非贪婪爬取
正则表达式在字符串方法中的使用:
方法名 | 说明 |
---|---|
public boolean matches(String regex) | 判断字符串是否满足正则表达式的规则 |
public String replaceAll(String regex, String newStr) | 按照正则表达式的规则进行替换 |
public String[] split(String regex) | 按照正则表达式的规则切割字符串 |
分组:
分组就是一个小括号
每组是有组号的,也就是序号
规则1:从1开始,连续不间断
规则2:以左括号为基准,最左边的是第一组,其次为第二组,以此类推
捕获分组:
捕获分组就是把这一组的数据捕获出来,再用一次
正则内部使用:\\组号
正则外部使用:$组号
需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
String regex1 = "(.).+\\1"; //\\组号:表示把第X组的内容取出来用一次
需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
String regex2 = "(.+).+\\1";
需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致
String regex3 = "((.)\\2*).+\\1";
需求:把重复的内容替换成单个的
String str = "我要学学编编编编程程程程程程";
String result = str.replaceAll("(.)\\1+", "$1");
非捕获分组:
分组之后不需要再用本组数据,仅仅是把数据括起来,不占用组号
符号 | 含义 | 举例 |
---|---|---|
(? : 正则) | 获取所有 | java(?:8|11|17) |
(? = 正则) | 获取前面部分 | java(?=8|11|17) |
(? ! 正则) | 获取不是指定内容的前面部分 | java(?!8|11|17) |
JDK7时间类
Date
世界标准时间:
以前的世界标准时间叫做格林尼治 / 格林威治时间(Greenwich Mean Time),简称GMT
目前的世界标准时间(UTC)已经替换为:原子钟
中国标准时间:
世界标准时间+8小时
Date时间类:
Date类是一个JDK写好的Javabean类,用来描述时间,精确到毫秒
利用空参构造创建的对象,默认表示系统当前时间
利用有参构造创建的对象,表示指定的时间(毫秒值)
构造方法:
方法名 | 说明 |
---|---|
public Date() | 创造Date对象,表示当前时间 |
public Date(long date) | 创建Date对象,表示指定时间 |
常用成员方法:
方法名 | 说明 |
---|---|
public void setTime(long time) | 设置/修改毫秒值 |
public long getTime() | 获取时间对象的毫秒值 |
SimpleDateFormat
SimpleDateFormat作用:
格式化:把时间变成我们喜欢的格式
解析:把字符串表示的时间变成Date对象,这样就可以对时间进行加减等操作
构造方法:
方法名 | 说明 |
---|---|
public SimpleDateFormat() | 构造一个SimpleDateFormat,使用默认格式 |
public SimpleDateFormat(String pattern) | 构造一个SimpleDateFormat,使用指定的格式 |
常用成员方法:
常用方法 | 说明 |
---|---|
public final String format(Date date) | 格式化(日期对象 -> 字符串) |
public Date parse(String source) | 解析(字符串 -> 日期对象) |
格式化的时间形式的常用的模式对应关系:
y —— 年,M —— 月,d —— 日,H —— 时,m —— 分,s —— 秒
举例:2023-11-11 13:27:06 —— yyyy-MM-dd HH:mm:ss
Calendar
Calendar代表了系统当前时间的日历对象,可以单独修改、获取时间中的年,月,日
细节:Calendar是一个抽象类,不能直接创建对象
获取Calendar日历类对象的方法:
方法名 | 说明 |
---|---|
public static Calendar getInstance() | 获取当前时间的日历对象 |
细节1:Calendar是一个抽象类,不能直接new,而是通过一个静态方法获取到子类对象
底层原理:会根据系统的不同时区来获取不同的日历对象,默认表示当前时间。会把时间中的纪元、年、月、日、时、分、秒、星期等等的都放到一个数组当中
细节2:
月份:范围0~11,如果获取出来的是0,实际上是1月
星期:1代表星期日,2代表星期一,以此类推
Calendar常用方法:
方法名 | 说明 |
---|---|
public final Date getTime() | 获取日期对象 |
public final setTime(Date date) | 给日历设置日期对象 |
public long getTimeInMillis() | 拿到时间毫秒值 |
public void setTimeInMillis(long millis) | 给日历设置时间毫秒值 |
public int get(int field) | 获取日历中的某个字段信息 |
public void set(int field, int value) | 修改日历的某个字段信息 |
public void add(int field, int amount) | 为某个字段添加 / 减少指定的值 |
对于字段信息的索引来说,java在Calendar类中,把索引对应的数字都定义成了常量
JDK8时间类
为什么要学JDK8新增时间相关类?
① 代码层面
JDK7:代码麻烦,日期对象的比较需要转换为毫秒值
JDK8:代码简单,新增的时间类中有判断的方法,以及计算时间间隔的方法
② 安全层面
JDK7:多线程环境下会导致数据安全的问题
JDK8:时间日期对象都是不可变的,解决了这个问题
JDK8新增时间类:
① Date类
ZoneId:时区
Instant:时间戳
ZonedDateTime:带时区的时间
② SimpleDateFormat类
DateTimeFormatter:用于时间的格式化和解析
③ 日历类
LocalDate:年、月、日
LocalTime:时、分、秒
LocalDateTime:年、月、日、时、分、秒
④ 工具类
Duration:时间间隔(秒,纳秒)
Period:时间间隔(年,月,日)
ChronoUnit:时间间隔(所有单位)
ZoneId时区:
Java定义时区的格式:洲名 / 城市名或国家名 / 城市名
方法名 | 说明 |
---|---|
static Set<String> getAvailableZoneIds() | 获取Java中支持的所有时区 |
static ZoneId systemDefault() | 获取系统默认时区 |
static ZoneId of(String zoneId) | 获取一个指定时区 |
Instant时间戳:
方法名 | 说明 |
---|---|
static Instant now() | 获取当前时间的Instant对象(标准时间) |
static Instant ofXxxx(long epochMilli) | 根据(秒 / 毫秒 / 纳秒)获取Instant对象 |
ZonedDateTime atZone(ZoneId zone) | 指定时区 |
boolean isXxx(Instant otherInstant) | 判断系列的方法 |
Instant minusXxx(long millisToSubstract) | 减少时间系列的方法 |
Instant plusXxx(long millisToSubtract) | 增加时间系列的方法 |
ZonedDateTime带时区的时间:
方法名 | 说明 |
---|---|
static ZonedDateTime now() | 获取当前时间的ZonedDateTime对象 |
static ZonedDateTime ofXxxx(…) | 获取指定时间的ZonedDateTime对象 |
ZonedDateTime withXxx(时间) | 修改时间系列的方法 |
ZonedDateTime minusXxx(时间) | 减少时间系列的方法 |
ZonedDateTime plusXxx(时间) | 增加时间系列的方法 |
DateTimeFormatter用于时间的格式化和解析:
方法名 | 说明 |
---|---|
static DateTimeFormatter ofPattern(格式) | 获取格式对象 |
String format(时间对象) | 按照指定方式格式化 |
LocalDate、LocalTime、LocalDateTime:
方法名 | 说明 |
---|---|
static XXX now() | 获取当前时间的对象 |
static XXX of(…) | 获取指定时间的对象 |
get开头的方法 | 获取日历中的年、月、日、时、分、秒等信息 |
isBefore,isAfter | 比较两个LocalDate |
with开头的 | 修改时间系列的方法 |
minus开头的 | 减少时间系列的方法 |
plus开头的 | 增加时间系列的方法 |
LocalDateTime转换为其他两个类的方法:
方法名 | 说明 |
---|---|
public LocalDate toLocalDate() | LocalDateTime转换成一个LocalDate对象 |
public LocalTime toLocalTime() | LocalDateTime转换成一个LocalTime对象 |
Duration、Period、ChronoUnit:
Duration:用于计算两个“时间”间隔(秒、纳秒)
Period:用于计算两个“日期”间隔(年、月、日)
ChronoUnit:用于计算两个“日期”间隔(所有单位)
包装类
包装类就是基本数据类型对应的引用类型(即将基本数据类型变成一个对象)
基本数据类型对应的包装类:
基本数据类型 | 对应的包装类 |
---|---|
byte | Byte |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
JDK5以前获取Integer对象的方式(了解):
方法名 | 说明 |
---|---|
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(String s, int radix) | 根据传递的字符串和进制创建一个Integer对象 |
这两种方式获取对象的区别(掌握):
构造方法创建的对象因为每一个都是new出来的,所以即使数据相同,每个对象也不一样;
静态方法创建的对象提前把-128~127
这个范围之间的数据创建好了对象,因此如果要用的时候不会创建新的对象,而是返回已经创建好的对象
JDK5以后,提出了一个新的机制:自动装箱和自动拆箱,因此,int和Integer可以看做是一个东西,因为在内部可以自动转化
自动装箱:把基本数据类型自动地变成其对应的包装类
自动拆箱:把包装类自动地变成其对象的基本数据类型
在底层,此时还会去自动调用静态方法valueOf得到一个Integer对象
Integer i1 = 10; //自动装箱
Integer i2 = 10;
Integer i3 = i1 + i2; //自动拆箱和装箱
Integer常用成员方法:
方法名 | 说明 |
---|---|
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:在类型转换的时候,括号中的参数只能是数字不能是其他,否则代码会报错
细节2:8种包装类当中,除了Character都有对应的parseXxx的方法,进行类型转换
键盘录入改进:
当我们在使用next,nextInt,nextDouble在接收数据的时候,遇到空格,回车,制表符的时候就停止了。因此,建议使用nextLine,可以接收一整行数据,然后再把数据转换成对应的类型
String line = sc.nextLine();
double v = Double.parseDouble(line);