JavaEE - 正则表达式、日期时间类、Math、Random、System、Runtime、大数值运算类

一、正则表达式

用来描述或者匹配一系列符合某个语句规则的字符串

正则表达式定义了字符串的模式,可以用来搜索、编辑或处理文本。

正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

1. 常用正则表达式

字符描述
\将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,‘n’ 匹配字符 “n”。’\n’ 匹配一个换行符。序列 ‘\\’ 匹配 “\” 而 “\(” 则匹配 “(”
^匹配输入字符串的开始位置
$匹配输入字符串的结束位置
*匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}
+匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}
?匹配前面的子表达式零次或一次。例如,“Mi(ku)?” 可以匹配 “Mi” 或 “Miku” 。? 等价于 {0,1}
{n}n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o
{n,}n 是一个非负整数。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等价于 ‘o+’。‘o{0,}’ 则等价于 ‘o*’
{n,m}m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格
?当该字符紧跟在任何一个其他限制符 * + ? {n} {n,} {n,m} 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,‘o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’
.匹配除换行符(\n、\r)之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用像"(.|\n)"的模式
\d匹配一个数字字符。等价于 [0-9]
\D匹配一个非数字字符。等价于 [^0-9]
\f匹配一个换页符。等价于 \x0c 和 \cL
\n匹配一个换行符。等价于 \x0a 和 \cJ
\r匹配一个回车符。等价于 \x0d 和 \cM
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]
\t匹配一个制表符。等价于 \x09 和 \cI
\v匹配一个垂直制表符。等价于 \x0b 和 \cK
\w匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
\W匹配非字母、数字、下划线。等价于 [^A-Za-z0-9_]。
\b匹配一个字边界,即字与空格间的位置。例如,“er\b"匹配"never"中的"er”,但不匹配"verb"中的"er"
\B非字边界匹配。“er\B"匹配"verb"中的"er”,但不匹配"never"中的"er"
()表示捕获分组,() 会把每个分组里的匹配的值保存起来,多个匹配值可以通过数字n来查看 (n是一个数字,表示第 n 个捕获组的内容)

2. 运算符优先级

正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。

运算符描述(从最高到最低)
\转义符
() (?:) (?=) []圆括号和方括号
* + ? {n} {n,} {n,m}限定符
^ $ \任何元字符、任何字符定位点和序列(即:位置和顺序)
|替换,“或"操作 字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food”。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"

案例:把一个字符串中的电话号码中间4位替换成* 如:130****1111

String str = "樱泽墨15112341111 英梨梨13012342222 加藤惠22233344455";
String regex = "(1\\d{2})(\\d{4})(\\d{4})";
//替换
String replaceAll = str.replaceAll(regex, "$1****$3");
System.out.println(replaceAll);
//底层源码:
//创建正则表达式的对象
//Pattern pattern = Pattern.compile(regex);
//获取匹配结果的对象
//Matcher matcher = pattern.matcher(str);
//替换
//String result = matcher.replaceAll("$1****$3");
//System.out.println(result);

3. Pattern类 & Matcher类

Pattern: 代表正则表达式的匹配模式

pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。

Matcher: 提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持

Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

案例1:校验QQ邮箱

String str = "5201314@qq.com";
String regex = "\\d{5,11}@qq\\.com";
//判断字符串str是否匹配正则表达式regex
boolean matches = str.matches(regex);
//底层源码:
//boolean matches = Pattern.matches(regex , str);
System.out.println(matches);//true

案例2:分隔路径

String str = "F:\\动漫\\穿越\\刀剑神域.mp4";
//匹配 :\\ 或	\\
String regex = ":?\\\\";
//依据正则表达式分隔字符串
String[] split = str.split(regex);
//底层源码
//创建匹配模式对象
//Pattern pattern = Pattern.compile(regex);
//String[] split = pattern.split(str);
for (String s : split) {
	System.out.println(s);
}
/*输出结果:
F
动漫
穿越
刀剑神域.mp4

案例3:用Pattern和Matcher 找到前端代码中的图片路径

String str = "<img src='wife/艾米莉娅.png'/><input type='image' src='submit.gif' /><img src='樱泽墨.jpg'/>";
String regex = "<img\\b[^>]*\\bsrc\\b\\s*=\\s*('|\")?([^'\"\n\r\f>]+(\\.jpg|\\.bmp|\\.eps|\\.gif|\\.mif|\\.miff|\\.png|\\.tif|\\.tiff|\\.svg|\\.wmf|\\.jpe|\\.jpeg|\\.dib|\\.ico|\\.tga|\\.cut|\\.pic)\\b)[^>]*>";
//获取正则表达式对象
Pattern pattern = Pattern.compile(regex);
//匹配结果
Matcher matcher = pattern.matcher(str);
//遍历匹配结果
while (matcher.find()) {
    String result = matcher.group(2);//获取正则表达式里第二个括号(组)里的内容
    System.out.println(result);
}
/*运行结果:
wife/艾米莉娅.png
樱泽墨.jpg
*/

System.out.println("在字符串中是否整个匹配:" + matcher.matches());//false
System.out.println("在字符串中是否开头就匹配:" + matcher.lookingAt());//true
System.out.println("在字符串中是否有包含匹配:" + matcher.find());//true

总结: Pattern与Matcher一起合作。Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持. 单独用Pattern只能使用Pattern.matches(String regex,CharSequence input)一种最基础最简单的匹配。


二、日期时间类

1. Date - 日期类

java.util.Date类表示特定的瞬间,精确到毫秒。

java.util 包提供了 Date 类来封装当前的日期和时间。Date 类提供两个构造函数来实例化 Date 对象。

1.构造函数使用当前日期和时间来初始化对象。

Date( )

Date date = new Date();
System.out.println(date);
// 星期 月份 日期  时:分:秒  时区  年份
// Thu  Jul  08  23: 09: 28  CST  2021

2.构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。

Date(long millisec)

//从1970.1.1 0:0:0往后推1000毫秒
Date date = new Date(1000);
System.out.println(date);
//Thu Jan 01 08:00:01 CST 1970
//中国统一采用东八区时间,所以时间加了8小时

2. SimpleDateFormat - 格式化日期类

SimpleDateFormat 是一个以语言环境敏感的方式来格式化和分析日期的类。允许选择任何自定义日期时间格式来运行。

SimpleDateFormat simpleDateFormatf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//格式化日期:date 转 字符串
String format = simpleDateFormatf.format(new Date());
System.out.println(format); //2021年07月08日 23:23:22

//解析:字符串 转 date
Date date = simpleDateFormatf.parse("Thu Jul 08 23:22:57 CST 2021");
System.out.println(date);// Thu Jul 08 11:37:48 CST 2021

日期和时间的格式化编码

字母描述示例
G纪元标记AD
y四位年份2001
M月份July or 07
d一个月的日期10
hA.M./P.M. (1~12)格式小时12
H一天中的小时 (0~23)22
m分钟数30
s秒数55
S毫秒数234
E星期几Tuesday
D一年中的日子360
F一个月中第几周的周几2 (second Wed. in July)
w一年中第几周40
W一个月中第几周1
aA.M./P.M. 标记PM
k一天中的小时(1~24)24
KA.M./P.M. (0~11)格式小时10
z时区Eastern Standard Time

3. Calendar - 日历类

Calendar类(日历)是一个抽象基类,主要用于完成日期字段之间相互操作的功能。即可以设置和获取日期数据的特定部分。

创建一个代表系统当前日期的Calendar对象

Calendar c = Calendar.getInstance();//默认是当前日期

创建一个指定日期的Calendar对象

使用Calendar类代表特定的时间,需要先创建一个Calendar的对象,然后再设定该对象中的年月日参数来完成。

//创建一个代表2021年7月8日的Calendar对象
Calendar c = Calendar.getInstance();
c.set(2021, 7 , 8);

Calendar类对象字段类型

常量描述
Calendar.YEAR年份
Calendar.MONTH月份
Calendar.DATE日期
Calendar.DAY_OF_MONTH日期,和上面的字段意义完全相同
Calendar.HOUR12小时制的小时
Calendar.HOUR_OF_DAY24小时制的小时
Calendar.MINUTE分钟
Calendar.SECOND
Calendar.DAY_OF_WEEK星期几
//获取当前日期的Calendar类的对象
Calendar c = Calendar.getInstance();
// 获得年份
int year = c.get(Calendar.YEAR);
// 获得月份(从0开始计算)
int month = c.get(Calendar.MONTH) + 1;
// 获得日期
int date = c.get(Calendar.DATE);
// 获得小时
int hour = c.get(Calendar.HOUR_OF_DAY);
// 获得分钟
int minute = c.get(Calendar.MINUTE);
// 获得秒
int second = c.get(Calendar.SECOND);
// 获得星期几(注意:1代表星期日、2代表星期一、3代表星期二,以此类推)
int day = c.get(Calendar.DAY_OF_WEEK);

System.out.println(date);//8
//把c对象的日期加上10,其它所有的数值会被重新计算
c.add(Calendar.DATE, 10);
System.out.println(c.get(Calendar.DATE));//18
//其他字段属性add的意义以此类推

//把c对象代表的年份设置为2008年,其他的所有数值会被重新计算
c.set(Calendar.YEAR,2008);
System.out.println(c.get(Calendar.YEAR));//2008
//其他字段属性set的意义以此类推

三、Math类

Math 包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数。
Math类是final类,Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。

1. Math类的常用方法

System.out.println("求次方:" + Math.pow(3, 2));//9.0
System.out.println("求平方根:" + Math.sqrt(9));//3.0
System.out.println("求绝对值:" + Math.abs(-100));//100
System.out.println("向上取整(天花板):" + Math.ceil(1.1));//2.0
System.out.println("向下取整(地板):" + Math.floor(1.9));//1.0
System.out.println("四舍五入:" + Math.round(1.4));//1
System.out.println("获取随机数0~1(不包含1):" + Math.random());//0.4523198926846782
System.out.println("最大值:" + Math.max(10, 20));//20
System.out.println("最小值:" + Math.min(10, 20));//10

注意: Math.round()是在参数的基础上加0.5然后向下取整,方法内部调用了floor方法

Math.round(-1.5)的结果是 -1

-1.5加0.5 等于 -1.0 向下取整就是 -1

需求:随机出1~100

System.out.println((int)(Math.random()*100)+1);

Math.abs();有可能返回负数吗?

System.out.println(Math.abs(Integer.MIN_VALUE));

首先我们看Math.abs()的源码:

public static int abs(int a) {
        return (a < 0) ? -a : a;
}

按照Java 语言规范的第15.15.4中,-x等于(~x)+1,其中~是位运算符。


也就是说int类型的最小值是-2147483648,首先进行了符号位的运算,把-2147483648(也就是符号1,后面31个1)转变成2147483647(符号位0,后面31个1),这里并不是之前数学上直接负负得正得到2147483648,显然这已经超过了int类型最大值。然后把得到的2147483647(这里已经是int类型的最大值),然后进行+1操作,得到了-2147483648(符号位1,后面31个1)。

2. 静态导入(了解)

当使用一个类里面的静态方法或者静态变量时,每次都需要写类名。如果不想写类名,想直接写方法名或者变量名,则可以考虑使用静态导入

语法:

import  static 包名.类名.*; //导入该类下的所有静态方法和常量

例如:

import static java.lang.Math.*;  //导入Math下的所有方法和变量(包括常量)
//代码中可以直接使用方面和变量名,而不需要前缀Math。
max(3,4);

缺点: 可读性差

如果自己写了同名方法,会优先调用(就近原则)

public static void main(String[] args) {
   System.out.println("求次方:" + pow(3, 2));//88888
   System.out.println("最大值:" + max(10, 20));//20
   System.out.println("最小值:" + min(10, 20));//10
   
}
public static int pow(int a,int b){
   return 88888;
}

四、Random类

此类用于生成随机数

1. Random随机类的使用

//创建一个随机数对象
Random random = new Random();
System.out.println("随机int值:" + random.nextInt());//1323220369
System.out.println("随机int值(0~9):" + random.nextInt(10));//5
System.out.println("随机boolean值:" + random.nextBoolean());//false
System.out.println("随机double值:" + random.nextDouble());//0.9319247552571699

需求:点名器

String[] names = {"樱岛麻衣","椎名真白","艾米莉娅","雷姆","加藤惠","一之濑千鹤","英梨梨","更科瑠夏","樱泽墨","本间芽衣子","小鸟游六花","莱卡"};
Random random = new Random();
int index = random.nextInt(names.length);
System.out.println(names[index]);

2. 深入理解Random的随机功能

生产随机数需要种子(Seed),且如果种子固定,random()每次运行生成的随机数(其实是伪随机数)也是固定的;因为返回的随机数是根据稳定的算法得出的稳定结果序列,并且Seed就是这个算法开始计算的第一个值

Random类中不含参构造方法每次都使用当前时间(纳秒)作为种子,而含参构造方法是以一个固定值作为种子。种子数固定,随机值也是固定的。
1毫秒=1k微妙=1m纳秒=1b皮秒

//设置种子数为1000
Random random = new Random(1000);
//因为种子数固定,结果并不随机,一直固定
System.out.println("随机int值:" + random.nextInt());//-1244746321
System.out.println("随机int值:" + random.nextInt(10));//5

五、System类

  • System类提供了一些静态属性和方法,允许通过类名直接调用。

  • System类提供了代表标准输入、标准输出、错误输出的类属性。

  • System类提供了一些静态方法用于访问环境变量、系统属性的方法。

1. System-系统类的属性

//系统标准的输入流(方向:控制台->程序)
InputStream inputStream = System.in;
Scanner scan = new Scanner(inputStream);
String next = scan.next();//输入字符串
scan.close();//关闭资源

//系统标准的输出流(方向:程序->控制台)
PrintStream out = System.out;
out.println(next);

//系统标准的错误输出流(方向:程序->控制台)
PrintStream err = System.err;
err.println(next);

研究System中的out和err

System.out.println("小明");
System.err.println("小红");
System.out.println("小强");

/*输出结果随机,例如
小明   小明   小红    小明小红
小强   小红   小明              ......
小红   小强   小强    小强
*/

out是一个线程中的代码
err也是一个线程中的代码
多线程随机性很强

2. System的方法

方法描述
exit(int status)退出当前虚拟机
currentTimeMillis()获得当前系统的毫秒值(与1970 年 1 月 1 日午夜之间的时间差)测试程序的消耗时间 - long
getProperties()获得当前的所有系统属性 - Properties
getProperty(String key)获得指定键的系统属性 - String
setIn(InputStream in)输入重定向
setOut(PrintStream out)输出重定向
setErr(PrintStream err)错误重定向
//获得当前系统的毫秒值(与1970 年 1 月 1 日00:00:00之间的时间差)
long currentTimeMillis = System.currentTimeMillis();
System.out.println(currentTimeMillis);//1625766335382
//获取到系统所有的参数
Properties properties = System.getProperties();
System.out.println(properties);
//通过key获取value
String value = System.getProperty("os.name");
System.out.println(value);//Windows 10
//关闭虚拟机
System.exit(0);

六、Runtime类

Runtime代表Java程序的运行时环境,可以通过 getRuntime 方法获取当前运行时。

应用程序不能自己创建Runtime对象,可以通过Runtime的静态方法getRuntime()获得Runtime对象。Runtime类可以访问jvm的相关信息,如处理器数量,内存信息等

//获取运算环境的对象
Runtime run = Runtime.getRuntime();
System.out.println("获取最大内存数:(字节)" + run.maxMemory());//3782737920
System.out.println("获取闲置内存数:(字节)" + run.freeMemory());//250001408
System.out.println("获取处理数:" + run.availableProcessors());//8

一段好的代码必须是运行时间快并且消耗内存少

七、大数值运算类

Java中提供了大数字的操作类在java.math包下的BigInteger和BigDecimal。这两个类用于高精度计算,大数以字符串的形式传入

BigInteger

针对大整数的处理类

BigInteger 类型的数字范围较 Integer 类型的数字范围要大得多。 Integer 是 int 的包装类, int 的最大值是 2³¹-1 ,如果要计算更大的数字,使用 Integer 数据类型就无法实现了,所以 Java 中提供了 BigInteger 类来处理更大的数字。 BigInteger 支持任意精度的整数,也就是说在运算中 BigInteger 类型可以准确地表示任何大小的整数值而不会丢失任何信息。

将 2147483648 转换为 BigInteger 类型 :

BigInteger intMax = new BigInteger("2147483648");
//参数是以字符串的形式存在
方法描述
BigInteger(String value)构造方法,将value字符串变成BigInteger类型数据
add(BigInteger value)加法,求两个BigInteger类型数据的和。
subtract(BigInteger value)减法,求两个BigInteger类型数据的差
multiply(BigInteger value)乘法,求两个BigInteger类型数据的积
divide(BigInteger divisor)除法,求两个BigInteger类型数据的商
modInverse(BigInteger m)取模,求BigInteger类型数据对m求模
remainder(BigInteger divisor)求余数,求BigInteger类型数据除以divisor的余数
abs()绝对值,求BigInteger类型数据的绝对值
negate()相反数,求BigInteger类型数据的相反数
max(BigInteger value)最大数,求两个BigInteger类型数据的最大值
min(BigInteger value)最小数,求两个BigInteger类型数据的最小值
BigInteger fifteen = new BigInteger("15");
BigInteger ten = new BigInteger("10");
BigInteger negateTen = new BigInteger("-10");

System.out.println("15+10= " + fifteen.add(ten));//25
System.out.println("15-10= " + fifteen.subtract(ten));//5
System.out.println("15*10= " + fifteen.multiply(ten));//150
System.out.println("15/10= " + fifteen.divide(ten));//1
//此方法的模数不能为负
System.out.println("15对10求模= " + fifteen.mod(ten));//5
//求余数时,结果的正负和被除数相同
System.out.println("15/10余数= " + fifteen.remainder(ten));//5
System.out.println("-10的绝对值= " + negateTen.abs());//10
System.out.println("15的相反数= " + fifteen.negate());//-15
System.out.println("15和10最大数= " + fifteen.max(ten));//15
System.out.println("15和-10最小数= " + fifteen.min(negateTen));//-10

利用BigInteger构造方法转换进制

String string1 = new BigInteger("15", 10).toString(2);
System.out.println("十进制的20转换成二进制是:" + string1);//1111
String string2 = new BigInteger("15", 10).toString(8);
System.out.println("十进制的20转换成八进制是:" + string2);//17
String string3 = new BigInteger("15", 10).toString(16);
System.out.println("十进制的20转换成十六进制是:" + string3);//f
String string4 = new BigInteger("110", 2).toString(10);
System.out.println("二进制的110转换成十进制是:" + string4);//6
String string5 = new BigInteger("110", 8).toString(10);
System.out.println("八进制的110转换成十进制是:" + string5);//72
String string6 = new BigInteger("110", 16).toString(10);
System.out.println("十六进制的110转换成十进制是:" + string6);//272

BigDecimal

针对大小数的处理类

BigDecimal 和 BigInteger 都能用来实现大数字的运算,不同的是 BigDecimal 加入了小数的概念。

BigDecimal 类型的数字可以用来做超大的浮点数的运算。 BigDecimal 类支持任何精度的定点数,可以用它来精确计算货币值。

BigDecimal 类中常用的两个构造方法

//实例化时将双精度型转换为 BigDecimal 类型
public BigDecimal(double val) 
//实例化时将字符串形式转换为 BigDecimal 类型
public BigDecimal(String val) 
方法描述
add(BigDecimal value)加法
subtract(BigDecimal value)减法
multiply(BigDecimal value)乘法
divide(BigDecimal value, int sacle ,int roundingMode)除法,方法中 3 个参数分别代表除数、小数点后的位数、近似处理模式
BigDecimal bigD1 = new BigDecimal("0.1");
BigDecimal bigD03 = new BigDecimal("0.03");
//加法运算
System.out.println("0.1+0.03= " + bigD1.add(bigD03));
//减法运算
System.out.println("0.1-0.03= " + bigD1.subtract(bigD03));
//乘法运算
System.out.println("0.1*0.03= " + bigD1.multiply(bigD03));
//除法运算   ROUND_HALF_UP  四舍五入
BigDecimal divide = bigD1.divide(bigD03, 5, BigDecimal.ROUND_HALF_UP);
System.out.println("0.1/0.03= " + divide);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值