文章目录
正则表达式
1.正则表达式概述、初体验
- 正则表达式可以用一些规定的字符来制定规则,并且来校验数据格式的合法性
- 需求:假如现在要求校验一个QQ号码是否正确,6位及20位之内,必须全部是数字
public class RegexDemo1 {
public static void main(String[] args) {
//需求:校验qq号码,必须全部数字,6~20位
System.out.println(checkQQ("1234567a"));
System.out.println(1234567);
System.out.println("123");
//正则表达式的初体验:
System.out.println(checkQQ2("234"));
}
public static boolean checkQQ2(String qq){
return qq!=null&&qq.matches("\\d{6,20}");
}
public static boolean checkQQ(String qq) {
//1.判断qq号码的长度
if (qq == null || qq.length() < 6 || qq.length() > 12) {
return false;
}
//2.判断qq中否全部是数字,不是返回false
//251425a87
for (int i = 0; i < qq.length(); i++) {
//获取每个字符
char ch = qq.charAt(i);
//判断字符是否为数字
if (ch < '0' || ch > '9') {
return false;
}
}
return true;
}
}
2.正则表达式的匹配原则
public class RegexDemo2 {
public static void main(String[] args) {
//public boolean matches(String regex);判断是否与正则表达式匹配,匹配返回true
//只能是a,b,a
System.out.println("a".matches("[abc]"));//true
System.out.println("z".matches("[abc]"));//false
//不能出现a b c
System.out.println("a".matches("[^abc]"));//false
System.out.println("z".matches("[^abc]"));//true
System.out.println("a".matches("\\d"));//false
System.out.println("2".matches("\\d"));//true
System.out.println("333".matches("\\d"));//false只能比较一个字符
System.out.println("z".matches("\\w"));//true
System.out.println("2".matches("\\w"));//true
System.out.println("21".matches("\\w"));//false;
System.out.println("你".matches("\\W"));//true
System.out.println("----------------------------");
//以上正确匹配只能校验单个字符
//校验密码
//必须是数字、字母、下划线、至少六位
System.out.println("abcdef".matches("\\w{6,}"));//true
System.out.println("abcf".matches("\\w{6,}"));//false
//验证码:必须是数字和字符,必须要4位
System.out.println("3453".matches("[a-zA-Z0-9]{4}"));//true
System.out.println("23-1".matches("[a-zA-Z0-9]{4}"));//false
System.out.println("23DF".matches("[\\w&&[^_]]{4}"));//true
}
}
3.正则表达式的常见案例
需求:请编写程序模拟用户输入手机号码,验证格式正确,并给出提示,直到格式输入正确为止
请编写程序模拟用户输入邮箱号码,验证格式正确,并给出提示,直到格式输入正确为止
请编写程序模拟用户输入电话号码,并给出提示,直到格式正确为止
public class RegexTest3 {
public static void main(String[] args) {
/**
* 需求:请编写程序模拟用户输入手机号码,验证格式正确,并给出提示,直到格式输入正确为止
* 请编写程序模拟用户输入邮箱号码,验证格式正确,并给出提示,直到格式输入正确为止
* 请编写程序模拟用户输入电话号码,并给出提示,直到格式正确为止
*/
//checkPhone();
//checkEmail();
//校验金额是否正确 99 0.5.99.5 010正确 0.354错误
System.out.println("1323".matches("\\d{1,10}\\.?\\d{0,2}"));
checkTel();
}
public static void checkPhone(){
Scanner sc=new Scanner(System.in);
while (true) {
System.out.println("请您输您的注册手机号");
String phone=sc.next();
//判断手机号码的格式是否正确
if(phone.matches("1[3-9]\\d{9}")){
System.out.println("手机号码格式正确。注册成功");
break;
}else{
System.out.println("格式有误");
}
}
}
public static void checkEmail(){
Scanner sc=new Scanner(System.in);
while (true) {
System.out.println("请您输入一个电子邮箱:");
String email=sc.next();
//判断邮箱的格式是否正确3268847878@qq.com
//判断邮箱的格式是否正确3268847dsda@163.com
//判断邮箱的格式是否正确3268847dsda878@pci.com.cn
if(email.matches("\\w{1,30}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z0-9]{2,20}){1,2}")){
System.out.println("您的电子邮箱格式正确,注册成功");
break;
}else{
System.out.println("您的电子邮箱格式有误");
}
}
}
public static void checkTel(){
Scanner sc=new Scanner(System.in);
while (true) {
System.out.println("请输入你的电话号码:");
String tel=sc.next();
//判断电话号码输入是否正确027-234575 027234575
if(tel.matches("0\\d{2,6}-?\\d{5,20}")){
System.out.println("您输入的电话号码格式正确,注册成功");
break;
}else{
System.out.println("您的格式有误,请重新输入");
}
}
}
}
4.正则表达式在方法中的应用
public String replaceAll(String regex,String newStr)//按照正则表达式匹配内容进行替换
public String[] spilt(String regex)//按照正则表达式匹配的内容进行分割字符串。返回一个字符串数组
public class RegexDemo04 {
/**
* public String replaceAll(String regex,String newStr)//按照正则表达式匹配内容进行替换
* public String[] spilt(String regex)//按照正则表达式匹配的内容进行分割字符串。返回一个字符串数组
*/
public static void main(String[] args) {
String names="小丽fgdh342小红cduihisg过儿";
String[] arrs=names.split("\\w+");
for(int i=0;i<arrs.length;i++){
System.out.println(arrs[i]);
}
String names2=names.replaceAll("\\w+"," ");
System.out.println(names2);
}
}
5.正则表达式爬取信息
public class RegexDemo05 {
public static void main(String[] args) {
String rs="来自黑马程序学习Java,电话020-43422424,或者联系邮箱"+
"itcast@itcast.cn,电话18762832633,0203232323"+
"邮箱bozai@itcast.cn,400-100-3233,4001003232";
//需求:从上面的内容中爬取出电话号码和邮箱
//1.定义爬取规则,字符串形式
String regex="(\\w{1,30}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z0-9]{2,20}){1,2})|" +
"(1[3-9]\\d{9})|(0\\d{2,6}-?\\d{5,20})|" +
"(400-?\\d{3,9}-?\\d{3,9})";
//2.把这个爬取规则编异成匹配对象
Pattern pattern=Pattern.compile(regex);
//3.得到一个内容匹配对象
Matcher matcher=pattern.matcher(rs);
//4.开始找了
while(matcher.find()){
String rs1=matcher.group();
System.out.println(rs1);
}
}
}
Array类
1.Arrays类概述、常用功能演示
- 数组操作工具类,专门用于操作数组元素的
1.1Arrays类的常用API
public static String toString(类型[] a)//对数组进行排序
public static void sort(类型[] a)//对数组进行默认升序排序
public static <T>void sort(类型[] a,Comparator<?super T>c)//使用比较器对象自定义排序
public static int binarySearch(int[] a,int key)//二分搜索数组中的数据,存在返回索引,不存在返回-1
public class ArraysDemo1 {
public static void main(String[] args) {
//目标:学会使用Arrays常用API,并理解其原理
int[] arr={10,2,55,23,24};
//1.返回数组内容 toString
// String rs=Arrays.toString(arr);
// System.out.println(rs);
System.out.println(Arrays.toString(arr));
//2.排序的API,自动对数组进行升序排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//3.二分搜索技术(前提数组必须排好序)
//返回不存在元素的规律:-(应该插入的元素+1)
int index=Arrays.binarySearch(arr,55);
System.out.println(index);
int index1=Arrays.binarySearch(arr,51);
System.out.println(index1);//-5:索引的搜索关键字,如果它是包含在数组;否则, (-(insertion point) - 1)。
//数字如果没有排好序,可能会找不到存在的元素,从而出现bug
int[] arr2={12,36,34,25,13,24,234,100};
int index2=Arrays.binarySearch(arr2,36);
System.out.println(index2);
}
}
2.Arrays类对于Comparator比较器的支持
自定义排序规则
- 设置Comparator接口对应的比较器对象,来定制比较规则
如果认为左边数据大于右边数据 返回正整数
如果认为左边数据小于右边数据 返回负整数
如果认为左边数据等于右边数据 返回0
public class Student {
private String name;
private int age;
private double height;
public Student() {
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
public class ArraysDemo2 {
public static void main(String[] args) {
//目标:自定义数组的排序规则:Comparator比较器对象
//1.Arrays的sort方法对于有值特性的数组是默认升序排序的
int[] ages={34,12,42,23};
Arrays.sort(ages);
System.out.println(Arrays.toString(ages));
//需求:降序排序(自定义比较器对象,只能支持引用类型的排序)
Integer[] ages1={34,12,42,23};
/**
* 参数一:被排序的数组,必须是引用类型的元素
* 参数二:匿名内部类对象,代表了一个比较器对象
*/
Arrays.sort(ages1,new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
//指定比较规则
// if(o1>o2){
// return 1;
// }else if(o1<o2){
// return -1;
// }
// return 0;
return o2-o1;//降序
}
});
System.out.println(Arrays.toString(ages1));
System.out.println("-------------------");
Student[] students=new Student[3];
students[0]=new Student("吴磊",23,175.5);
students[1]=new Student("小花",18,185.5);
students[2]=new Student("小米",20,195.5);
System.out.println(Arrays.toString(students));
//Arrays.sort(students);//直接运行崩溃
//自己指定比较规则
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//自己指定比较规则
//return o2.getAge()-o1.getAge();//按照年龄升序排序
//return Double.compare(o1.getHeight(),o2.getHeight());//比较浮点型可以这样写 升序
return Double.compare(o2.getHeight(),o1.getHeight());//比较浮点型数据,降序
}
});
System.out.println(Arrays.toString(students));
}
}
常见算法
1.选择排序
public static void main(String[] args) {
//1.定义数组
int[] arr={5,1,3,2};
//2.定义一个循环,控制选择几轮
for(int i=0;i<arr.length-1;i++){
//i=0; j 1,2,3
//i=1; j 2,3
//i=2; j 3
//i=3;
//定义内部循环,选择控制几次
for(int j=i+1;j<arr.length;j++){
//当前位为arr[i]
//如果比当前位更小的,则交换
if(arr[i]>arr[j]){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
2.二分查找
基本查找:在数据量很大的时候,基本查找从前往后寻找的性能是很差的
二分查找:
- 二分查找性好,但前提是必须先对数据进行排序
public class Test2 {
public static void main(String[] args) {
//1.定义数组
int[] arr={10,14,16,25,28,30,35,88,100};
System.out.println(binarySearch(arr,35));
System.out.println(binarySearch(arr,350));
}
/**
* 二分查找算法的实现
* @param arr 排序的数组
* @return 索引,如果元素不存在,直接放回-1
*/
public static int binarySearch(int[] arr,int data){
//定义左边位置和右边位置
int left=0;
int right=arr.length-1;
//2.开始循环,折半查找
while(left<=right){
//取中间索引
int middleIndex=(left+right)/2;
//3.判断当前中间元素和要找的元素的大小情况
if(data>arr[middleIndex]){
//往右边找,左位置更新为中间索引+1
left=middleIndex+1;
}else if(data<middleIndex){
//往左边找,右边位置=中间索引-1
right=middleIndex-1;
}else{
return middleIndex;
}
}
return -1;
}
}
结论:二分查找正常的检索条件应该是开始位置left<=结束位置max
Lambda表达式枚举
1.Lambda概述
- JDK8开始的新语法形式
- 作用:简化匿名内部类代码的简化
Lambda表达式的简化格式
(匿名内部类被重写方法的形参列表)->{
被重写方法的方法体代码
}
注:->是语法格式,无实际含义
public class LambdaDemo2 {
//目标:学会使用Lambda的标准格式,简化匿名内部类的代码形式
//Lambda只能简化接口中只有一个抽象方法的匿名类
public static void main(String[] args) {
// Swimming s1=new Swimming(){
// @Override
// public void swim(){
// System.out.println("老师游泳");
// }
// };
Swimming s1=()->{
System.out.println("老师游泳");
};
go(s1);
System.out.println("-------------------");
go(()-> {
System.out.println("学生游泳很开心。。。。");
});
// go(new Swimming() {
// @Override
// public void swim() {
// System.out.println("学生游泳很开心");
// }
// });
}
public static void go(Swimming s){
System.out.println("开始");
s.swim();
System.out.println("结束");
}
}
@FunctionalInterface//一旦加上这个注解必须是函数式接口,里面只能有一个抽象方法
interface Swimming{
void swim();
}
注:Lambda表达式只能简化函数式接口的匿名内部类的写法形式
- 什么是函数式接口?
1.首先必须是接口,其次接口中有且仅有一个抽象方法的形式
2.通常我们会在接口上加一个@Functionallnterface注释,标记该接口必须是满足函数式接口
2.Lambda实战-简化常见函数式接口
public class LambdaDemo3 {
public static void main(String[] args) {
Integer[] ages1={34,12,42,23};
/**
* 参数一:被排序的数组,必须是引用类型的元素
* 参数二:匿名内部类对象,代表了一个比较器对象
*/
Arrays.sort(ages1,(Integer o1, Integer o2)-> {
return o2-o1;//降序
});
System.out.println(Arrays.toString(ages1));
}
}
3.Lambda表达式的省略规则
- 参数类型可以省略不写
- 如果只有一个参数,参数类型可以省略,同时()也可以省略
- 如果Lambda表达式的方法体只有一行代码,可以省略大括号不写,同时要省略分号!
- 如果Lambda表达式的方法体代码只有一行代码,可以省略大括号不写。此时,如果这行代码是return语句,必须省略reutrn不写,同是也必须省略“;”不写