Java笔记_11
- 一、常用的API
- 1.1、Math
- Math练习
- 1.2、System
- 1.3、Runtime
- 1.4、Object
- 1.5、浅克隆、深克隆
- 1.6、对象工具类的Objects
- 1.7、BigInteger(大整数)
- 1.8、BigDecimal(大小数)
- 二、正则表达式
- 2.1、正则表达式基础知识
- 2.2、正则表达式-练习1
- 2.3、正则表达式-练习2
- 2.4、爬虫
- 2.5、带条件爬取、贪婪爬取和识别正则的两个方法
- 2.6、捕获分组和非捕获分组
- 三、JDK7时间
- 3.1、JDK7时间-Date
一、常用的API
1.1、Math
- 是一个帮助我们进行数学计算的工具类
- 私有化构造方法,所有的方法都是静态的
Math类的常用方法
方法名 | 说明 |
---|---|
public static int abs(int a) | 获取参数绝对值 |
public static doublie ceil(double a) | 向上取整 |
public static doublie floor(double a) | 向下取整 |
public static int round(float a) | 四舍五入 |
public static int max(int a,int b) | 获取两个int值中的较大值 |
public static doublie pow(double a,double b) | 返回a的b次幂的值 |
public static doublie random() | 返回为double的随机值,范围[0.0,1.0) |
public static doublie sqrt(double a) | 返回平方根 |
public static doublie cbrt(double a) | 返回立方根 |
Math练习
- 判断是否为质数
public static boolean isProme(int a){
for (int i = 1; i <Math.sqrt(a) ; i++) {
if(a%i==0){
return false;
}
}
return true;
}
- 获取四叶玫瑰数
int count = 0;
for (int i = 1000; i < 9999; i++) {
int ge = i%10;
int shi = i/10%10;
int bai = i/100%10;
int qian = i/1000%10;
double sum = Math.pow(ge,4)+Math.pow(shi,4)+Math.pow(bai,4)+Math.pow(qian,4);
if(sum==i){
count++;
System.out.println(i);
}
}
System.out.println(count);
1.2、System
- System也是工具类,提供一些与系统相关的方法
计算机中的时间原点
1970年1月1日 08:00:00
我国在东八区,有八小时的时差
原因:
1969年8月,贝尔实验室的程序员肯汤普逊利用妻儿离开一个月的机会。开始着手创造一个全新的革命性的操作系统。他使用B编译语言在老旧的PDP-7机器上开发出了Unix的一个版本。随后,汤普逊和同事丹尼斯里奇改进了B语言,开发出了C语言,重写了UNIX。
1970年1月1日 算C语言的生日
- 1秒 = 1000毫秒
- 1毫秒 = 1000微秒
- 1微秒 = 1000纳秒
方法名 | 说明 |
---|---|
public static void exit(int status) | 终止当前运行的Java虚拟机 |
public static long currentTimeMillis() | 返回当前系统的时间毫秒值形式 |
public static void arraycopy(数据源数组,起始索引,目的地索引,起始索引,拷贝个数) | 数组拷贝 |
使用arraycopy
时注意事项:
- 如果数据源数组和目的地数组两者都是基本数据类型,两者的数据类型必须保持一致,否则会进行报错
- 在拷贝的时候需要考虑数组的长度,如果超出范围也会报错
- 如果数据源数组和目的地数组都是引用数据类型,那么子类类型可以赋值给父类类型
1.3、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命令 |
exec
命令关机 shutdown(加上参数才能执行)
- -s :默认在1分钟之后关机
- -s -t 指定时间:指定关机时间
- -a :取消关机操作
- -r :关机并重启
1.4、Object
- Object是Java中的顶级父类。所有的类都直接或间接的继承于Object类。
- Object类中的方法可以被所有子类访问,所以我们要学习Object类和其中的方法
方法名 | 说明 |
---|---|
public String toString() | 返回对象的字符串表示形式 |
public boolean equals(object obj) | 比较两个对象是否相等 |
protected object clone(int a) | 对象克隆 |
println()
:方法
- 参数:表示打印的对象
- 核心逻辑:当我们打印一个对象的时候,底层会调用对象的toString方法,把对象变成字符串。然后再打印在控制台上,打印完毕换行处理。
toString
方法结论:
- 如果我们打印一个对象,想要看到属性值的话,那么就重写tostring方法就可以了。
- 在重写的方法中,把对象的属性值进行拼接。
equals
方法结论:
- 如果没有重写equals方法,那么默认使用object中的方法进行比较,比较的是地址值是否相等
- 一般来讲地址值对于我们意义不大,所以我们会重写,重写之后比较的就是对象内部的属性值了。
String
中的equals
方法
- 先判断参数是否为字符串如果是字符串,再比较内部的属性
- 但是如果参数不是字符串,直接返回false
StringBulider
中的equals
方法
- 在StringBuilder当中,没有重写equals方法使用的是object中的在Object当中默认是使用
==
号比较两个对象的地址值
1.5、浅克隆、深克隆
- 把A对象的属性值完全拷贝给B对象,也叫对象拷贝,对象复制
细节:
方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去
书写细节:
- 重写Object中的clone方法
- 让javabean类实现Cloneable接口
- 创建原对象并调用clone就可以了。
Cloneable
- 如果一个接口里面没有抽象方法表示当前接口是一个标志性接口,现在
Cloneable
表示一旦实现了,那么当前类的对象就可以被克隆
- 浅克隆
Object中的克隆是浅克隆
重写的代码块
protected Object clone() throws CloneNotSupportedException{
//调用父类中的clone方法
//相当于让java帮我们克隆一个对象,并把克隆之后的对象返回
return super clone();
}
- 深克隆
重写的clone()方法
protected Object clone() throws CloneNotSupportedException{
//调用父类中的clone方法
//相当于让java帮我们克隆一个对象,并把克隆之后的对象返回
int[] data = this.data;
int[] data2 = new int[data.length];
for (int i = 0; i < data.length; i++) {
data2[i] = data[i];
}
User u =(User) super.clone();
u.data = data2;
return u;
}
1.6、对象工具类的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的结果相反 |
细节:
- 方法的底层会判断 第一个对象 是否为null,如果为null,直接返回false
- 如果 第一个对象 不为null,那么就利用 第一个对象 再次调用equals方法
- 此时 第一个对象 是 设置的对象 类型,所以最终还是会调用 设置的对象 中的equals方法。
- 如果没有重写,比较地址值,如果重写了,就比较属性值。
1.7、BigInteger(大整数)
BigInteger构造方法
方法名 | 说明 |
---|---|
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的对象,内部有优化 |
- 对象一旦创建,内部记录的值不能发生改变
valueOf(long val)
方法中会对 -16~16 之间的值进行优化,会创建好这些数字的对象,当赋值在这个范围内使用==
号对比两个对象得到的是true
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) | 除法,获取商和余数(数组0索引是商,1索引是余数) |
public boolean equals(Object x) | 比较是否相同 |
public BigInteger pow(int exponent) | 次幂 |
public BigInteger max/min(BigInteger val) | 返回较大值/较小值 |
public int intValue(BigInteger val) | 转为int类型整数,超出范围数据有误 |
1.8、BigDecimal(大小数)
BigDecimal的作用
- 用于小数的精确计算
- 用来表示很大的小数
BigDecimal的构造方法
方法 | 说明 |
---|---|
public BigDecimal( double val) | 通过double来获得一个小数 (得到的小数有可能不精确) |
public BigDecimal( String val) | 通过String获得一个小数 |
public static BigDecimal valueOf( double val) | 静态方法创建一个对象 |
细节:
- 如果要表示的数字不大,没有超出double的取值范围,建议使用静态方法
- 如果要表示的数字比较大,超出了double的取值范围,建议使用构造方法
- 如果我们传递的是0~10之间的整数,包含0,包含10,那么方法会返回已经创建好的对象,不会重新new
BigDecimal的使用
方法名 | 说明 |
---|---|
public static BigDecimal valueof(double val) | 获取对 |
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,精确几位,舍入模式) | 除法 |
舍入模式(举例):
- UP:远离零方向舍入的舍入模式
- DOWN:向零方向舍入的舍入模式
- CEILING:向正无限大方向舍入的舍入模式
- FLOOR:向负无限大方向舍入的舍入模式
- HALF_UP:小数距离两个数之间距离相等时向上舍入
- HALF_DOWN:小数距离两个数之间距离相等时向下舍入
二、正则表达式
2.1、正则表达式基础知识
正则表达式的作用:
- 校验字符串是否满足规则
- 在一段文本中查找满足要求的内容
字符类(只能匹配一个字符)
字符 | 作用 |
---|---|
[abc] | 只能是a, b,或c |
[^abc] | 除了a, b, c之外的任何字符 |
[a-zA-Z] | a到zA到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]一个非单词字符 |
\
在Java中是转义字符
\\
表示前面的\
是一个转义字符,改变了后面\
原本的含义,把他变成了一个普普通通的\
数量词
字符 | 作用 |
---|---|
X? | X,一次或0次 |
X* | X,零次或多次 |
X+ | X,一次或多次 |
x{n} | X,正好n次 |
X{n,} | X,至少n次 |
X{n,m} | X,至少n但不超过m次 |
2.2、正则表达式-练习1
package API_.RegexDome;
public class Test1 {
public static void main(String[] args) {
//验证手机号码 13112345678 17665063261 13112345678
String regex1 = "1\\d{10}";
System.out.println("13112345678".matches(regex1));
System.out.println("17665063261".matches(regex1));
System.out.println("13112345678".matches(regex1));
System.out.println("131123456782".matches(regex1));
System.out.println("-------------------------------------------------");
//验证座机电话号码 020-2324242 02122442 027-42424 0712-3242434
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));
System.out.println("-------------------------------------------------");
//验证邮箱号码 3232323@qq.com zhangsan@itcast.cnn dlied0009@163.com dle13121@pci.com.cn
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("dlied0009@163.com".matches(regex3));
System.out.println("dle13121@pci.com.cn".matches(regex3));
}
}
2.3、正则表达式-练习2
(?i)
可以忽略后面字母的大小写- 编写正则的小心得
- 按照正确的数据进行拆分
- 找每一部分的规律,并编写正则表达式
- 把每一部分的正则拼接在一起,就是最终的结果
- 书写的时候:从左到右去书写。
package API_.RegexDome;
public class Test2 {
public static void main(String[] args) {
//用户名要求
String regex1 = "\\w{4,16}";
System.out.println("zhangsan_123".matches(regex1));
System.out.println("--------------------------------------------");
//身份证号码验证
String regex2 = "[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]";
System.out.println("411423200006012222".matches(regex2));
}
}
2.4、爬虫
Pattern类:表示正则表达式
Matcher类:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。
package API_.RegexDome;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test3 {
public static void main(String[] args) {
String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
//获取正则表达式对象
Pattern p = Pattern.compile("Java\\d{0,2}");
//获取文本匹配器对象
//m:文本匹配器对象
//str:大串
//p:规则
//m要在str中找到符合p规则的小串
Matcher m = p.matcher(str);
//拿着文本匹配器从头开始读取,寻找是否有满足规则的字串
//如果没有,方法返回false
//如果有,返回true,在底层记录字串的其实索引和结束索引+1
boolean b = m.find();
//方法底层会根据find方法记录的索引进行字符串的截取
// subString(起始索引,结束索引);包头不包尾
//(0,4)但是不包含4索引
String s1 = m.group();
System.out.println(s1);
}
}
2.5、带条件爬取、贪婪爬取和识别正则的两个方法
- 定义正则表达式
?
理解为前面的数据=
表示在Java后面要跟随的数据:
表示获取的是所有的与之类型相关的字符!
表示获取去除带有后面跟随数据的相关字符串- 获取的数据是括号之前的
package API_.RegexDome;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test4 {
public static void main(String[] args) {
/*需求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也会逐渐登上历史舞台";
//需求一:
String regex1 = "((?i)java)(?=8|11|17)";//(?i)忽略大小写
//需求二:
String regex2 = "((?i)java)(8|11|17)";
String regex3 = "((?i)java)(?:8|11|17)";
Pattern p =Pattern.compile(regex3);
Matcher m = p.matcher(s);
while (m.find()){
System.out.println(m.group());
}
}
}
贪婪爬取:尽可能地多获取数据
非贪婪爬取:尽可能地少获取数据
- Java中,默认的就是贪婪爬取
- 在定义的正则中有出现
+
时在其后面加上?
即可使其变为非贪婪爬取
正则表达式在字符串方法中的使用
方法名 | 说明 |
---|---|
public String[ ] matches (String regex) | 判断字符串是否满足正则表达式的规则 |
public String replaceAll(String regex, String newStr) | 按照正则表达式的规则进行替换 |
public String[ ] split(String regex) | 按照正则表达式的规则切割字符串 |
package API_.RegexDome;
public class Test5 {
public static void main(String[] args) {
String s = "例阿斯顿asdasdasda啊实打实的asdadas";
String result = s.replaceAll("[\\w&&[^_]]+","vs");
System.out.println(result);
String[] arr = s.split("[\\w&&[^_]]+");
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
2.6、捕获分组和非捕获分组
- 分组就是一个小括号
- 每一组都是有组号的,也就是序号
- 规则1:从1开始,连续不间断
- 规则2:以左括号为基准,最左边的是第一组,其次是第二组,以此类推
\\组号
将某一组的数据拿出来再用一次
package API_.RegexDome;
public class Test6 {
public static void main(String[] args) {
//需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
// 举例:a123a b456b 17891 &abc& a123b(false)
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("a123a".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:把首字母拿出来再次使用
String regex3 = "((.)\\2*)\\w+\\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("-------------------------------------------------");
}
}
- 捕获分组:
\\组号
——在正则内部捕获$组号
——在正则外部捕获
package API_.RegexDome;
public class Test7 {
public static void main(String[] args) {
String s = "我我我我我我我要要要要要要学学学学学学编编编编编编编编程程程程程";
String result = s.replaceAll("(.)\\1+","$1");
System.out.println(result);
}
}
非捕获分组
符号 | 含义 | 举例 |
---|---|---|
(?:正则) | 获取所有 | Java(?:8|11|17) |
(?=正则) | 获取前面部分 | Java(?=8|11|17) |
(?!正则) | 获取不是指定内容的前面部分 | Java(?!8|11|17) |
- 分组之后不需要再用本组数据,仅仅把数据括起来,不占组号
三、JDK7时间
3.1、JDK7时间-Date
世界标准时间:
格林尼治时间/格林威治时间(Greenwich Mean Time)简称GMT。
目前世界标准时间((UTC)已经替换为:原子钟
中国标准时间:
世界标准时间+8小时
时间换算单位:
1秒 = 1000毫秒
1毫秒 = 1000微秒
1微秒 = 1000纳秒
Date时间类
Date类是一个JDK写好的Javabean类,用来描述时间,精确到毫秒。
利用空参构造创建的对象,默认表示系统当前时间。
利用有参构造创建的对象,表示指定的时间。