Java基础学习
一、常用方法(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. toString
Object 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方法,先判断参数是否为字符串
//如果是字符串,再比较内部的属性
//但是如果参数不是字符串,直接返回false
System.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.01000000000000000020816681711721685132943093776702880859375
System.out.println(bd2);//0.0899999999999999966693309261245303787291049957275390625
通过传递字符串的形式进行创建对象:
BigDecimal bd3 = new BigDecimal("0.01");
BigDecimal bd4 = new BigDecimal("0.09");
System.out.println(bd3);//0.01
System.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]]"));//false
System.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));//true
System.out.println("Abc".matches(regime3));//true
System.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。在底层记录子串的起始索引和结束索引+1
boolean 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&&[^_]]+";
//将中间的英文替换成VS
String 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));//true
System.out.println("b456b".matches(regex1));//true
System.out.println("17891".matches(regex1));//true
System.out.println("&123&".matches(regex1));//true
System.out.println("&123a".matches(regex1));//false
需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符:
String regex2 = "(.+).+\\1";
System.out.println("bbba456bbba".matches(regex2));//true
System.out.println("123789123".matches(regex2));//true
System.out.println("&!!!123&!!!".matches(regex2));//true
System.out.println("&&123&&a".matches(regex2));//false
需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致:
// (.) 把首字母看做一组
// \\2 把首字母拿出来再次使用
// *作用于\\2,表示后面重复的内容出现0次或多次
String regex3 = "((.)\\2*).+\\1";
System.out.println("aaaa123aaaa".matches(regex3));//true
System.out.println("bbbb456bbbb".matches(regex3));//true
System.out.println("11117891111".matches(regex3));//true
System.out.println("&&&&123&&&&".matches(regex3));//true
System.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);
}
}