AIP就是Java已经写好的各种功能的java类
目录
1.Math
2.System
3.Runtime
4.Object
5.对象工具类Objects
6.BIgInteger
7.BigDecima
8.正则表达式
(1)爬虫
(2)带条件爬取,贪婪爬取和识别正则的两个方法
(3)捕获分组和非捕获分组
9.JDK7以前时间相关类
10.JDK8新增时间相关类
11.包装类
12.综合练习
1.Math
工具类:类名知其意,私有化构造方法,方法定义为静态。
Math是进行数学计算的工具类
Math的sqrt,开平方
Math的cbrt,开立方
Math的ceil(英语:天花板),是向上取整
Math的floor(英语:地板),是向下取整
Math的random的取值范围,0.0是闭区间(包括0.0),1.0是开区间(不包括1.0)
Math的abs有个bug,比如,int类型的取值范围是 -2147483648~2147483647,如果Math.abs(-2147483648)的结果还是 -2147483648,因为int的范围不包括正数2147483648。
如果用Math.absExact(-2147483648),超出范围会报错
练习:判断一个数是否为质数
左边的因子小于等于平方根,右边的因子大于等于平方根。所以只用遍历平方根左边的因子即可
public class MathDemo {
public static void main(String[] args) {
System.out.println(getPrime(7));
}
public static boolean getPrime(int number) {
for (int i = 2; i <=Math.sqrt(number); i++) {
if (number%i==0){
return false;
}
}
return true;
}
}
练习:自幂数,一个n位自然数等于自身各个数位上数字的n次幂之和
要求1:统计一共有多少个水仙花数。
要求2:证明没有两位的自幂数。
要求3:分别统计有多少个四叶玫瑰数和五角星数(答案都为3)
//要求1:统计一共有多少个水仙花数。
public class MathDemo {
public static void main(String[] args) {
int count=0;
for (int i = 100; i <=999; i++) {
int ge=i%10;
int shi=i/10%10;
int bai=i/100%10;
double result=Math.pow(ge,3)+Math.pow(shi,3)+Math.pow(bai,3);
if (i==result){
count++;
System.out.println(i);
}
}
System.out.println(count+"个");
}
}
//要求2:证明没有两位的自幂数。
public class MathDemo {
public static void main(String[] args) {
int count=0;
for (int i = 10; i <=99; i++) {
int ge=i%10;
int shi=i/10%10;
double result=Math.pow(ge,2)+Math.pow(shi,2);
if (i==result){
count++;
System.out.println(i);
}
}
System.out.println(count+"个");
}
}
//要求3:分别统计有多少个四叶玫瑰数和五角星数(答案都为3)
public class MathDemo {
public static void main(String[] args) {
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 result=Math.pow(ge,4)+Math.pow(shi,4)+Math.pow(bai,4)+Math.pow(qian,4);
if (i==result){
count++;
System.out.println(i);
}
}
System.out.println(count+"个");
}
}
//----------------------------------------------------------------
public class MathDemo {
public static void main(String[] args) {
int count=0;
for (int i = 10000; i <=99999; i++) {
int ge=i%10;
int shi=i/10%10;
int bai=i/100%10;
int qian=i/1000%10;
int wan=i/10000%10;
double result=Math.pow(ge,5)+Math.pow(shi,5)+Math.pow(bai,5)+Math.pow(qian,5)+Math.pow(wan,5);
if (i==result){
count++;
System.out.println(i);
}
}
System.out.println(count+"个");
}
}
2.System
System也是一个工具类,提供了一些与系统相关的方法
1.如果数据源数组和目的地数组都是基本数据类型,两者类型必须保持一致,否则会报错
2.拷贝的时候需要考虑数组长度,超出范围,也会报错
3.如果数据源数组和目的地数组都是引用数据类型,子类类型可以赋值给父类
3.Runtime
1.Runtime表示当前虚拟机的运行环境
2.这个类里的方法不是静态的,想要调用方法,就要获取Runtime的对象。
3.Runtime的对象不能直接new,要用getRuntime()
4.Object
在顶级父类中只有无参的构造方法,因为不可能有所有事物的共性,也就没有参数
1.如果打印一个对象,想要看到属性值,那就要重写toString方法。
2.在重写方法中,把对象的属性值进行拼接。
1.如果没有重写equals方法,那么默认使用Object中的方法进行比较,比较地址值是否相等。
2.一般地址值对于我们意义不大,所以会重写,重写之后比较的是对象内部的属性值。
对象克隆,把A对象的属性值完全拷贝给B,也叫对象拷贝,对象复制
字符串在串池中,复用。
5.对象工具类Objects
Objects是一个对象工具类,提供了一些操作对象的方法。
6.BIgInteger
BIgInteger是个对象,不能直接加减乘除等计算,都要用方法来完成。
将二进制数按规则(32位为一组)分割,然后存到数组中,数组中第二个是补码
7.BigDecima
BigDecima作用:1.用于小数的精确运算。
2.用来表示很大的小数
1.如果表示的数字不大,没有超出double的取值范围,建议使用静态方法。
2.如果表示的数字比较大,超出了double的取值范围,建议使用构造方法。
3.如果传递的是0~10的之间整数,包括0和10,那么方法会返回已经创建好的对象,不会重
新new,(10.0就会使用new,因为10.0不是int类型)。
存储方式:遍历每个字符,然后转换为ascii码,放到数组中存储。
8.正则表达式
作用:1.校验字符串是否满足规则
2.在一段文本中查找满足要求的内容
类:pattern(在api文档查看)
1.正则表达式中,从左到右,一个一个匹配。
2.[ ] 方括号表示一个范围 ,在这个范围里只能匹配一个字符。
3.{ }大括号表示匹配字符个数。例:{6,}至少匹配6个字符,{4}只匹配4个字符。
4.如果要求两个范围的交集,要用&&,不能只写一个,一个&只是一个简单的符号。
5.” \d “等使用时,需要加个” \ “(转义)
6.( )小括号表示分组。
7. (?i)问号和字符i组合,可以忽略它后面字符的大小写。a(?i)bc,这个就会忽略bc的大小
写,所以 aBC是true。
编写写正则表达式: 1.按照正确数据进行拆分
2.找出每部分规律,并编写正则表达式,每部拼接起来就是完整表达式
3.从左到右书写
练习:
用正则表达式验证用户输入的手机号码是否满足要求,13276898988,13245647587
用正则表达式验证用户输入的邮箱是否满足要求,2909378766@qq.com,zhangsan@itcast.cnn
用正则表达式验证用户输入的座机电话号码是否满足要求,020-2323343,0712-2425687
public class RegexDemo {
public static void main(String[] args) {
//匹配电话号码13276898988,15245647587
//第一位一定是1,第二位在3~9之间,后面的数字随机
String regex1="1[3-9]\\d{9}";
System.out.println("13276898988".matches(regex1)); //true
System.out.println("15245647587".matches(regex1)); //true
System.out.println("-------------------------");
//匹配邮箱是否满足要求,2909378766@qq.com,zhangsan@itcast.cnn,dlei0009@pci.com.cn
//@前面部分:\w+
String regex2="\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}";
System.out.println("2909378766@qq.com".matches(regex2));
System.out.println("zhangsan@itcast.cnn".matches(regex2));
System.out.println("dlei0009@pci.com.cn".matches(regex2));
System.out.println("-------------------------");
//匹配座机电话号码是否满足要求,020-2323343,0712-2425687,0212453424
//?表示匹配-,0次或1次
//-后面数字的第一位不能为0
String regex3="0\\d{2,3}-?[1-9]\\d{4,9}";
System.out.println("020-2323343".matches(regex3)); //true
System.out.println("0712-2425687".matches(regex3)); //true
System.out.println("0212453424".matches(regex3)); //true
System.out.println("-------------------------");
}
}
练习:用正则完成以下需求
验证用户名是否满足要求:
大小写字母,数字,下划线一共4-16位。
验证身份证号码是否满足要求:
简单要求:18位,前17位任意数字,最后一位可以是数字,可以是大写或小写的x。
复杂要求:按照身份证号码的格式严格要求。
public class RegexDemo {
public static void main(String[] args) {
//用户名校验
//大小写字母,数字,下划线一共4-16位。
String regex1="\\w{4,16}";
System.out.println("zhangannn".matches(regex1)); //true
System.out.println("xxxx_ssss".matches(regex1)); //true
System.out.println("-----------------");
//乱写的511364874323458473,51156497432345847x,51136987432645847X
//18位,前17位任意数字,最后一位可以是数字,可以是大写或小写的x。
String regex2="[1-9]{17}[\\dxX]"; //或者[1-9]{17}(\\d|x|X)或者[1-9]{17}(\\d|(?i)x)
System.out.println("511364874323458473".matches(regex2));
System.out.println("51156497432345847x".matches(regex2));
System.out.println("51136987432645847X".matches(regex2));
System.out.println("-----------------");
//身份证号码严格校验
//前面6位:省份,市区,派出所等信息,第一位不能为0,后面5位是任意数字 [1-9]\\d{5}
//年份前半段:18,19,20 年份后半段:任意数字出现两次 (18|19|20)\\d{2}
//月份:01~09 10 11 12 (0[1-9]|1[0-2])
//日期:01~31 (0[1-9]|[12]\\d|3[01])
//最后四位:任意数字出现3次,最后一位可以是数字也可以是大写或小写的x \\d{3}(\\d|(?i)x)
String regex3="[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|(?i)x)";
System.out.println("51156187405291747x".matches(regex3));//错误的身份证false
System.out.println("51136197404202047X".matches(regex3));//错误的身份证false
System.out.println("513723180111050521".matches(regex3));//正确的身份证true
}
}
(1)爬虫
Pattern:表示正则表达式
Matcher:文本匹配器,作用是按照正则表达式的规则去读取字符串,从头开始读取
(在大串中去找符合匹配规则的子串)
1.获取正则表达式的对象
Pattern p=Pattern.compile("Java\\d{0,2}");
2.获取文本匹配器的对象
Matcher m=p.matcher(str);
3.查找匹配内容是否存在
m.find();
4.获取查找到的能匹配的内容
m.group();
练习
本地爬虫和网络爬虫
有如下文本,请按照要求爬取数据。
Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和ava11,因为这
两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台。
要求:找出里面所有的JavaXX
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo {
public static void main(String[] args) {
String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这\n" +
"两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
Pattern p=Pattern.compile("Java\\d{0,2}");
Matcher m=p.matcher(str);
while (m.find()){
System.out.println(m.group());
}
}
}
练习
需求:把下面文本中的电话,邮箱,手机号,热线都爬取出来。
来黑马程序员学习Java,
电话:18512516758,18512508907
或者联系邮箱:boniu@itcast.cn,
座机电话:01036517895,010-98951256
邮箱:bozai@itcast.cn,
热线电话:400-618-9090,400-618-4000,4006184000,4006189090
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo {
public static void main(String[] args) {
String str="练习\n" +
"需求:把下面文本中的电话,邮箱,手机号,热线都爬取出来。\n" +
"来黑马程序员学习Java,\n" +
"手机号:18512516758,18512508907\n" +
"或者联系邮箱:boniu@itcast.cn,\n" +
"座机电话:01036517895,010-98951256\n" +
"邮箱:bozai@itcast.cn,\n" +
"热线电话:400-618-9090,400-618-4000,4006184000,4006189090";
//邮箱:\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}
//座机:010-?\\d{8}
//手机:1[3-9]\d{9}
//热线:400-?618-?[49]0[09]0
String regex="\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}|010-?\\d{8}|1[3-9]\\d{9}|400-?618-?[49]0[09]0";
Pattern p=Pattern.compile(regex);
Matcher m=p.matcher(str);
while (m.find()){
System.out.println(m.group());
}
}
}
(2)带条件爬取,贪婪爬取和识别正则的两个方法
贪婪爬取:尽可能多的爬取数据。
非贪婪爬取:尽可能少的爬取数据。
(Java中默认贪婪爬取)
(3)捕获分组和非捕获分组
分组就是一个()小括号
练习: 捕获分组就是把这一组的数据捕获出来,再用一次。
需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
举例: a123a b456b 17891 &abc&
需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
举例: abc123abc b456b 123789123 &!@abc&!@
需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致
举例: aaa123aaa bbb456bbb 111789111 &&abc&&
public class RegexDemo {
public static void main(String[] args) {
// 需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
// 举例: a123a b456b 17891 &abc&
// 需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
// 举例: abc123abc b456b 123789123 &!@abc&!@
// 需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致
// 举例: aaa123aaa bbb456bbb 111789111 &&abc&&
//需求1
String regex="(.).+\\1";
System.out.println("a123a".matches(regex));//true
System.out.println("b456b".matches(regex));//true
System.out.println("17891".matches(regex));//true
System.out.println("&abc&".matches(regex));//true
System.out.println("-------------------");
//需求2
String regex1="(.+).+\\1";
System.out.println("abc123abc".matches(regex1));//true
System.out.println("b456b".matches(regex1));//true
System.out.println("123789123".matches(regex1));//true
System.out.println("&!@abc&!@".matches(regex1));//true
System.out.println("-------------------");
//需求3
//(.)表示一个任意字符,把它看成一组
String regex2="((.)\\2*).+\\1";
System.out.println("aaa123aaa".matches(regex2));//true
System.out.println("bbb456bbb".matches(regex2));//true
System.out.println("111789111".matches(regex2));//true
System.out.println("&&abc&&".matches(regex2));//true
}
}
练习:口吃替换
需求:将字符串:我要学学编编编编程程程程程
替换为:我要学编程
public class RegexDemo {
public static void main(String[] args) {
String str="我要学学编编编编程程程程程";
String regex="(.)\\1+";
String result=str.replaceAll(regex,"$1");
System.out.println(result);
}
}
9.JDK7以前时间相关类
练习:将2000-11-11转换成2000年11月11日
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class RegexDemo {
public static void main(String[] args) throws ParseException {
String str="2000-11-11";
//解析
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date d=sdf.parse(str);
//格式化
SimpleDateFormat sdf1=new SimpleDateFormat("yyyy年MM月dd日");
String result=sdf1.format(d);
System.out.println(result);
}
}
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class RegexDemo {
public static void main(String[] args) throws ParseException {
String startTime="2023年11月11日 0:00:00";
String endTime="2023年11月11日 0:10:00";
String clickTimeJ="2023年11月11日 0:01:00";
String clickTimeP="2023年11月11日 0:11:00";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 H:mm:ss");
Date start = sdf.parse(startTime);
Date end = sdf.parse(endTime);
Date xiaoJ = sdf.parse(clickTimeJ);
Date xiaoP = sdf.parse(clickTimeP);
method(start, end, xiaoJ); //参加上了
method(start, end, xiaoP); //没参加上
}
public static void method(Date start, Date end, Date xiao) {
if (start.getTime()<=xiao.getTime()&&end.getTime()>=xiao.getTime()){
System.out.println("参加上了");
}
else{
System.out.println("没参加上");
}
}
}
1.Calendar是一个抽象类,不能直接new,而是通过一个静态方法获取到子类对象。
2.底层原理:会根据系统的不同时区来获取不同的日历对象,默认表示当前时间。
会把时间中的纪元,年,月,日,时,分,秒,星期,等等放到一个数组中。
10.JDK8新增时间相关类
Instant.now()获取对象
上面两个是静态的,要用类名来调用;下面的要用对象来调用。
11.包装类
包装类:基本数据类型对应的引用类型
(简言说,就是将基本数据类型变成一个对象)
键盘输入用nextLine(),然后进行类型转换。
12.综合练习
练习1:键盘录入一些1~100的整数,并添加到集合中,直到集合内数据和超过200为止。
import java.util.ArrayList;
import java.util.Scanner;
public class Test {
public static void main(String[] args){
//创建集合
ArrayList<Integer> al=new ArrayList<>();
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("请输入1~100的数字:");
String line = sc.nextLine();
Integer num = Integer.parseInt(line);
if (num<1||num>100){
System.out.println("不符合要求");
continue;
}
al.add(num);
int sum=0;
for (int i = 0; i < al.size(); i++) {
sum=sum+al.get(i);
}
if (sum>=200){
System.out.println(sum);
return;
}
}
}
}
练习2:自己实现parseInt方法的效果,将字符串形式的数据转成整数。
要求:字符串里只能是数字,不能有其他字符
最少一位,最多十位
0不能开头
public class Test {
public static void main(String[] args){
String str="12345";
String regex="[1-9]\\d{0,9}";
if(!str.matches(regex)){
System.out.println("数据错误");
}else{
int result=0;
for (int i = 0; i < str.length(); i++) {
int num=str.charAt(i)-'0';
result=result*10+num;
}
System.out.println(result+1);//可以进行运算,所以已经转换成int类型了
}
}
}
练习3:
定义一个方法自己实现toBinaryString方法的效果,将一个十进制整数转成字符串表示的二进制。
public class Test {
public static void main(String[] args){
int num=8;
String str=toBinaryString(num);
System.out.println(str);
}
private static String toBinaryString(int num) {
StringBuilder sb=new StringBuilder();
while (num!=0){
int remiandar=num%2;
//倒着拼接数据
sb.insert(0,remiandar);
num=num/2;
}
String result=sb.toString();
return result;
}
}
练习4:使用代码实现计算你活了多少天,用JDK7和JDK8的两种方式完成
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
public static void main(String[] args) throws ParseException {
//JDK7计算要用毫秒值
//出生日期的毫秒值
String birthday="2001-12-05";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date birthTime = sdf.parse(birthday);
long time=birthTime.getTime();
//当前日期的毫秒值
long time2=System.currentTimeMillis();
//当前日期-出生日期
long result=time2-time;
result=result/1000/60/60/24;
System.out.println(result);
//JDK8
LocalDate ld1=new LocalDate.of(2001,12,05);
LocalDate ld2=new LocalDate.now();
long days=ChronoUnit.DAYS.between(ld1,ld2);
System.out.println(days);
}
}
练习5:判断任意的一个年份是闰年还是平年。
要求:用JDK7和JDK8的两种方式完成
提示:二月有29天是闰年,一年366天是闰年
import java.text.ParseException;
import java.time.LocalDate;
import java.util.Calendar;
public class Test {
public static void main(String[] args) throws ParseException {
//JDK7
Calendar c=Calendar.getInstance();
c.set(2000,2,1);//表示3月1号
//把日历往前减一天,如果前一天是29就是闰年
c.add(Calendar.DAY_OF_MONTH,-1);
int days=c.get(Calendar.DAY_OF_MONTH);
if (days==29){
System.out.println("闰年");
}
//JDK8
LocalDate ld=LocalDate.of(2000,3,1);
LocalDate days1 = ld.minusDays(1);
int days2=days1.getDayOfMonth();
//System.out.println(days2);
if (days2==29){
System.out.println("闰年");
}
}
}