Java基础学习(9)
Java基础学习
- 一、常用方法(API)
-
- 1.1 Math
- 1.2 System
- 1.3 Runtime
- 1. 4 、object
- 1.5 Objects
- 1.6 BigInteger
-
- BigInteger底层存储方式
- 1.7 BigDecima
-
- 计算机中的小数
- BigDecimal的使用
- 1.8 正则表达式
- 二、爬虫
-
-
- 正则表达式在字符串方法中的使用
- 正则表达式中的分组
- 捕获分组
- 三、JDK7时间-Date
-
- 3.1 Date时间类
- 3.2 simpleDateFormat 类作用
- 3.3 Calendar类
-
一、常用方法(API)
1.1 Math
- 是一个帮助我们用于进行数学计算的工具类
私有化构造方法,所有的方法都是静态的
int num1 = Math.abs(-88);//8
int num2 = Math.abs(88);//88
如果是int类型,要注意范围-2147483648~2147483647,若果这个整型的负数找不到与之对应的正数就会报错
1.2 System
数组拷贝
int[] arr1 = {1,2,3,4,5,6,7,8,9,10];
int[] arr2 = new int[];
System.arraycopy(arr1,0,arr2,0,10);
for(int i =0;i<arr.length;i++){System.out.print(arr[i])
}//1,2,3,4,5,6,7,8,9,10
注意事项(数组copy)
1. 如果两个数组为基本数据类型,这两个数组必须是相同的数据类型,不相同就会报错
2. 再拷贝的时候,就必须考虑到数组的长度,超出长度就会报错
1.3 Runtime
- Runtime表示当前虚拟机的运行环境
//1.获取Runtime对象
// Runtime r1 = Runtime.getRuntime();
// Runtime r2 = Runtime.getRuntime();
// boolean result = (r1==r2);//true,因为在Runtime里面只能有一个对象来表示环境变量// 2. exit停止虚拟机 --> 0: 正常关闭 1:不正常关闭
// Runtime.getRuntime().exit(1);//3. 获取到CPU当中的线程数
// System.out.println(Runtime.getRuntime().availableProcessors());//4. JVM获取到的总共内存大小
// System.out.println(Runtime.getRuntime().maxMemory());//5. JVM已经获取的内存大小
// System.out.println(Runtime.getRuntime().totalMemory());//6. JVM剩余的空间大小
// System.out.println(Runtime.getRuntime().freeMemory());//7.运行cmd命令/*shutdown加上参数才能执行-s默认在1分钟之后关机.-s -t 指定时间 :指定关机时间-a: 取消关机操作-r关机并重启:*/System.out.println(Runtime.getRuntime().exec("qq"));
1. 4 、object
object成员方法
//1. toStringObject obj = new Object();String str = obj.toString();System.out.println(str);//Object@4eec7777
toString结论:
如果我们打印一个对象,想要看到属性值的话,那么就重写tostring方法就可以了。 在重写的方法中,把对象的属性值进行拼接。
equals方法:
Sting s = "abc";
StringBuilder sb = new StringBuilder("abc");System.out.println(s.equals(sb));// false
//因为equals方法是被s调用的,而s是字符串
//所以equals要看string类中的
//字符串中的equals方法,先判断参数是否为字符串
//如果是字符串,再比较内部的属性
//但是如果参数不是字符串,直接返回falseSystem.out.printIn(sb.equals(s));// false
//因为equals方法是被sb调用的,而sb是stringBuilder
//所以这里的equals方法要看stringBuilder中的equals方法
//那么在stringBuilder当中,没有重写equals方法
//使用的是其父类object中的equals方法
//在object当中默认是使用==号比较两个对象的地址值
//而这里的s和sb记录的地址值是不一样的,所以结果返回false
对象克隆(clone)
- 把A对象的属性值完全拷贝给B对象,也叫对象拷贝,对象复制
//1.先创建一个对象
int[] data = (1, 2, 3, 4, 5, 6, 7, 8, 9,1, 11, 12, 13, 14, 15, 0);
User u1 = new User( id: 1, username: "zhangsan", password: "1234qwer", path: "girl11",data);//2.克隆对象
//细节:
//方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去。//书写细节:
//1.重写object中的clone方法
//2.让javabean类实现cloneable接口
//3.创建原对象并调用clone就可以了。User u2 = (User) u1.clone();
System.out.println(u1);
System.out.println(u2);
浅克隆:
- 不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来
Object :浅拷贝 ----> 若要深拷贝重新写方法
深克隆:
- 基本数据类型拷贝过来
- 字符串复用
- 引用数据类型会重新创建新的
总结:
- object是]ava中的顶级父类 所有的类都直接或间接的继承于object类。
- tostring(): 一般会重写,打印对象时打印属性
- equals():比较对象时会重写,比较对象属性值是否相同4clone():默认浅克隆 如果需要深克隆需要重写方法或者使用第三方工具类
1.5 Objects
- objects是一个工具类,提供了一些方法去完成一些功能
Objects里面的equals源码:
public static boolean equals (Object a,Object b){return (a==b) || ((a != null) && a.equals(b));
}
1.方法的底层会判断s1是否为nu11,如果为nu11,直接返回false
2.如果s1不为nul1,那么就利用s1再次调用equals方法
3.此时s1是student类型,所以最终还是会调用student中的equals方法。
equals 如果没有重写,比较地址值,如果重写了,就比较属性值。
1.6 BigInteger
- 用来表示整数的大小
BigInteger构造方法:
获取一个随机的大整数:
//获取一个随机的大整数Random r =new Random();BigInteger bi = new BigInteger(4,r);//获取一个[0~2^4]的一个数
获取一个指定的大整数
//获取一个指定的大整数BigInteger bi1 = new BigInteger("99999999999999999999");System.out.println(bi1);
获取一个指定进制的大整数
BigInteger bi2 = new BigInteger("132",4);System.out.println(bi2);//30
1.字符串中的数字必须是整数
2.字符串中的数字必须要跟进制吻合。
比如二进制中,那么只能写@和1,写其他的就报错。
BigInteger构造方法当中的注意事项:
- 如果BigInteger表示的数字没有超出long的范围,可以用静态方法获取
- 如果BigInteger表示的超出long的范围,可以用构造方法获取
- 对象一旦创建,BigInteger内部记录的值不能发生改变
- 只要进行计算都会产生一个新的BigInteger对象
BigInteger的常见的成员方法:
BigInteger底层存储方式
- 对于计算机而言,其实是没有数据类型的概念的,都是
0101010101
- 数据类型是编程语言自己规定的。
1.7 BigDecima
- 用于小数的精确计算
- 用来表示很大的小数
通过传递double形式创建小数:
BigDecimal bd1 = new BigDecimal(0.01);BigDecimal bd2 = new BigDecimal(0.09);System.out.println(bd1);//0.01000000000000000020816681711721685132943093776702880859375System.out.println(bd2);//0.0899999999999999966693309261245303787291049957275390625
通过传递字符串的形式进行创建对象:
BigDecimal bd3 = new BigDecimal("0.01");BigDecimal bd4 = new BigDecimal("0.09");System.out.println(bd3);//0.01System.out.println(bd4);//0.09
通过静态方法来创建对象:
BigDecimal bd5 = BigDecimal.valueOf(10);System.out.println(bd5);//10
细节:
- 如果要表示的数字不大,没有超出double的取值范围,建议使用静态方法
- 如果要表示的数字比较大,超出了double的取值范围,建议使用构造方法
- 如果我们传递的是g~19之间的整数,包含0,包含18,那么方法会返回已经创建好的对象,不会重新new
计算机中的小数
BigDecimal的使用
BigDecimal bd1 = BigDecimal.valueOf(0.21);BigDecimal bd2 = BigDecimal.valueOf(0.79);//加法BigDecimal bd3 = bd1.add(bd2);System.out.println(bd3);//1.00//减法BigDecimal bd4 = bd1.subtract(bd2);System.out.println(bd4);//-0.58//除法(这个方法必须得整除,除不尽会报错)BigDecimal bd5 = BigDecimal.valueOf(9);BigDecimal bd6 = BigDecimal.valueOf(3);BigDecimal bd7 = bd5.divide(bd6);System.out.println(bd7);
UP
:表示远离0进位成整数 0.5–>1;-0.5–>-1
DOWN
,与UP规则相反进位
HALF-UP
:=四舍五入
1.8 正则表达式
作用:
- 校验字符串是否满足规则
- 在一段文本中查找满足要求的内容
细节:如果要求两个范围的交集,那么需要写符号&&如果写成了一个&,那么此时&表示就不是交集了,而是一个简简单单的&符号
System.out.println("a".matches("[a-z&&[0-9]]"));//falseSystem.out.println("a".matches("[a-z&[0-9]]"));//true
验证其手机号码
String regime1 = "1[3-9]\\\\d{9}";System.out.println("18683320044".matches(regime1));
验证邮箱号码
String regime2 = "\\\\d{11}\\\\W[1][6][3]\\\\.\\\\w{1,}";System.out.println("18683230044@163.com".matches(regime2));
忽略书写时的大小写:
String regime3 = "(?i)abc";System.out.println("abc".matches(regime3));//trueSystem.out.println("Abc".matches(regime3));//trueSystem.out.println("ABC".matches(regime3));//true
二、爬虫
Pattern:表示正则表达式
Matcher: 文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。在大串中去找符合匹配规则的子串。
爬虫底层原理所需代码:
//需要爬虫的对象String str = "Java埃松觉得害怕哇阿松大【建瓯阿斯顿,Java8阿松大阿松大,Java14撒地方";//获取正则表达式对象Pattern p =Pattern.compile("Java\\\\d{0,2}");//获取文本匹配器的对象// m: 文本匹配器的对象// str: 大串// p: 规则// m要在str中找符合p规则的小串Matcher m = p.matcher(str);//拿着文本匹配器从头开始读取,寻找是否有满足规则的子串// 如果没有,方法返回false//如果有,返回true。在底层记录子串的起始索引和结束索引+1boolean b = m.find();//0,4//方法底层会根据find方法记录的索引进行字符串的截取// substring(起始索引,结束索引); 包头不包尾// (e,4) 但是不包含4索引// 会把截取的小串进行返回。String s1 = m.group();System.out.println(s1);
爬虫获取数据代码:
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class 爬虫练习 {public static void main(String[] args) {/*需求:把下面文本中的座机电话,邮箱,手机号,热线都爬取出来。来黑马程序员学习Java,手机号: 18512516758,18512508997或者联系邮箱: boniu@itcast.cn,座机电话: 01036517895,010-98951256邮箱: bozai@itcast.cn,热线电话: 409-618-9090,400-618-4000,40061840,4006189090手机号码校验:[1-9]\\\\d{10}邮箱校验:\\\\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}*/String str = "来黑马程序员学习Java," +" 手机号: 18512516758,18512508997" +" 或者联系邮箱: boniu@itcast.cn," +" 座机电话: 01036517895,010-98951256" +" 邮箱: bozai@itcast.cn," +" 热线电话: 409-618-9090,400-618-4000,40061840,4006189090";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})";//获取正则表达式的对象Pattern p = Pattern.compile(regex);//获取文本匹配器对象Matcher m = p.matcher(str);//利用循环将所有符合数据的内容爬取出来while (m.find()){String s1 = m.group();System.out.println(s1);}}
}
?:
:数据为……
?!
: 数据不为……
?i
数据不区分大小写
String str = "java , Java8,JAVa11,JAVA17";
String regex1 = "((?i)java)(8|11|17)";//爬出来结果:Java8 JAVa11 JAVA17
String regex2 ="((?i)java)(?:8|11|17)"//爬出来结果:Java8 JAVa11 JAVA17
String regex3 ="((?i)java)(?!8|11|17)"//爬出来结果:java
String regex4 ="((?i)java)(?=8|11|17)" //爬出来结果:Java JAVa JAVA
Java当中,默认的就是贪婪爬取如果我们在数量词+ * 的后面加上问号,那么此时就是非贪婪爬取
ab+ 贪婪爬取: abbbbbbbbbbbb 非贪婪爬取: ab
正则表达式在字符串方法中的使用
public class 正则表达式的改切 {public static void main(String[] args) {//需要修改切割的对象String str = "小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠";//定义正则表达式(中间的英文)String regex = "[\\\\w&&[^_]]+";//将中间的英文替换成VSString result = str.replaceAll(regex,"VS");System.out.println(result);//将名字全部取出,因为返回的为字符串数组,所以用字符串数组接收(从中间的英文进行切割)String[] arr = str.split(regex);for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}
}
正则表达式中的分组
图中的红色为第一组,蓝色为第二组,绿色为第三组
需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符:
String regex1 = "(.).+\\\\1";System.out.println("a123a".matches(regex1));//trueSystem.out.println("b456b".matches(regex1));//trueSystem.out.println("17891".matches(regex1));//trueSystem.out.println("&123&".matches(regex1));//trueSystem.out.println("&123a".matches(regex1));//false
需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符:
String regex2 = "(.+).+\\\\1";System.out.println("bbba456bbba".matches(regex2));//trueSystem.out.println("123789123".matches(regex2));//trueSystem.out.println("&!!!123&!!!".matches(regex2));//trueSystem.out.println("&&123&&a".matches(regex2));//false
需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致:
// (.) 把首字母看做一组// \\\\2 把首字母拿出来再次使用// *作用于\\\\2,表示后面重复的内容出现0次或多次String regex3 = "((.)\\\\2*).+\\\\1";System.out.println("aaaa123aaaa".matches(regex3));//trueSystem.out.println("bbbb456bbbb".matches(regex3));//trueSystem.out.println("11117891111".matches(regex3));//trueSystem.out.println("&&&&123&&&&".matches(regex3));//trueSystem.out.println("&aaa123aaaa".matches(regex3));//false
捕获分组
- 正则内部使用:\\组号
- 正则外部使用:$组号
治疗口吃:
String str = "我要学编编编编编编编编程程程";String regex = "(.)\\\\1+";String result = str.replaceAll(regex,"$1");System.out.println(result);//我要学编程
非捕获分组不会被识别为\\\\1
三、JDK7时间-Date
3.1 Date时间类
- Date 类是一个IDK写好的lavabean类,用来描述时间,精确到毫秒
- 利用空参构造创建的对象,默认表示系统当前时间
- 利用有参构造创建的对象,表示指定的时间
原理:
//创建时间原点的时间Date d1 = new Date(0);//创建当前时间Date d2 = new Date();//获取到当时的时间距离时间原点的毫秒值long result = d2.getTime();//设置时间long time = 1000L*12;d1.setTime(time);
3.2 simpleDateFormat 类作用
- 格式化:把时间变成我们喜欢的格式。
- 解析:把字符串表示的时间变成Date对象。
格式化的时间形式的常用的模式对应关系如下:
3.3 Calendar类
注意事项:
Calendar是一个抽象类,不能直接new,而是通过一个静态方法获取到子类对象
月份是 0~11
老外把星期天当作每个星期的第一天 ;1(星期日) 2(星期一) 3(星期二) 4(星期三) 5(星期四)6(星期五) 7(星期六)
import java.util.Calendar;
import java.util.Date;public class calendar {public static void main(String[] args) {//创建一个Calendar对象Calendar c = Calendar.getInstance();//修改一下日历时间Date d = new Date(100000L);c.setTime(d);System.out.println(c);c.set(Calendar.YEAR,2023);c.set(Calendar.MONDAY,11);c.set(Calendar.DAY_OF_WEEK,5);c.set(Calendar.DAY_OF_MONTH,5);//增加或减少月份,正数为+,负数为减c.add(Calendar.YEAR,1);c.add(Calendar.MONTH,-1);int year = c.get(Calendar.YEAR);int month = c.get(Calendar.MONTH)+1;int date = c.get(Calendar.DAY_OF_MONTH);int week = c.get(Calendar.DAY_OF_WEEK);System.out.println(year+", "+month+", "+date+", "+week);}
}