Bootstrap

自制笔记 | Java基础——常用API(正则表达式、Math、Object、BigDecimal、时间类等)(持续更新...)

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
\\d0-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:用于计算两个“日期”间隔(所有单位)

包装类

包装类就是基本数据类型对应的引用类型(即将基本数据类型变成一个对象)

基本数据类型对应的包装类:

基本数据类型对应的包装类
byteByte
shortShort
charCharacter
intInteger
longLong
floatFloat
doubleDouble
booleanBoolean

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);
;