java中的正则表达式,泛型<T>,try-catch-throw...异常处理

 正则表达式:

就是一些特定的字符串组成,代表的就是一个规则。在用作校验数据格式是否可发,更简单,更便捷。

书写规则:
String提供了一个匹配正则表达式的方法 

public boolean matches(String regex)判断字符串是否匹配正则表达式,匹配返回true,不匹配返回false。

 

案例初体验:

检验一个qq号码是否符合格式


public class RegexDemo1 {
    public static void main(String[] args) {
        System.out.println(checkQQ("251425789"));
        System.out.println(checkQQ("051425789"));
        System.out.println(checkQQ("2514ab2579"));
        System.out.println(checkQQ("2514"));
        System.out.println(checkQQ(null));

    }

    /**
     * 判断传入的qq号码的是否是合格的
     * @param number
     * @return
     */
    private static boolean checkQQ(String number) {
        if (number == null || number.startsWith("0") || number.length() < 6 || number.length() > 20){
            return false;
        }
        for (int i = 0; i < number.length(); i++) {
            char c = number.charAt(i);
            if (c < '0' || c > '9'){
                return false;
            }
        }
            return true;
    }

 
}

上面繁琐的代码,就是为了验证传入的QQ号码是否符合格式,我们可以用正则表达式进行改进。


public class RegexDemo1 {
    public static void main(String[] args) {

        System.out.println(checkQQ2("251425789"));
        System.out.println(checkQQ2("051425789"));
        System.out.println(checkQQ2("2514ab2579"));
        System.out.println(checkQQ2("2514"));
        System.out.println(checkQQ2(null));
    }

   
    public static Boolean checkQQ2(String str){
        return   str != null && str.matches("[1-9]\\d{5,19}");
    }
}
应用案例:
检验用户输入的电话号码是否符合格式:
 检查输入的手机号是否符合格式
 13548494739
023-4343
012213131

public class CheckPhone {
    public static void main(String[] args) {
        checkPhone();
    }

    /**
     * 检查输入的手机号是否符合格式
     * 13548494739
     *023-4343
     *012213131
     */
    public static  void checkPhone(){
        while (true) {
            System.out.println("请输入你要注册的手机号:");
            Scanner sc= new Scanner(System.in);
            String phone = sc.next();
            if (phone != null && phone.matches("(1[3-9]\\d{9})|(0[1-9]\\d{1,9}-?\\d{2,10})")){
                    System.out.println("注册成功");
                    break;
                }else {
                System.out.println("注册失败,格式不正确");
            }
        }

    }
}
检验email格式是否符合要求:
* 检验输入的邮箱是否符合格式
 12121212@qq.com
 dsds@163.com
 sundaoen@qq.com.cn

public class EmailCheck {
    public static void main(String[] args) {
        checkEmail();
    }

    /**
     * 检验输入的邮箱是否符合格式
     * 12121212@qq.com
     * dsds@163.com
     * sundaoen@qq.com.cn
     */
    public static void checkEmail(){
        Scanner sc = new Scanner(System.in);
        while (true){
            System.out.println("请输入你要添加的邮箱:");
            String email = sc.next();
            if (email.matches("\\w{2,25}@\\w{2,10}(\\.\\w{2,10}){1,2}")){
                System.out.println("添加成功");
                break;
            }else {
                System.out.println("添加失败,你输入的格式有误");
            }
        }
    }
}
使用正则表达式查找文本中的内容:


public class TextRegexDemo {
    public static void main(String[] args) {
        String data = "来学校进行学习Java,\n" +
                "电话:18512516758,18512508907\n" +
                "或者联系邮箱: boniu@itcast.cn\n" +
                "座机电话:01036517895,010-98951256\n" +
                "邮箱:bozai@itjava.cn,\n" +
                "邮箱2:dlei0009@163.com,\n" +
                "热线电话:400-618-9090 ,400-618-4000,\n" +
                "4006184000,4006189090\n";
        // 创建一个匹配规则对象,封装正则表达式
        String regex = "(1[3-9]\\d{9})|((0[1-9]\\d{1,4})-?[1-9]\\d{4,9})|(\\w{2,30}@\\w{2,20}(\\.\\w{2,10}){1,2})" +
                "|(400-?[1-9]\\d{2,5}-?[1-9]\\d{2,5})";
        Pattern pattern = Pattern.compile(regex);
        //把内容和爬取规则建立联系,得到一个匹配对象
        Matcher matcher = pattern.matcher(data);
        //开始使用匹配器对象,爬取内容
        while (matcher.find()){
            System.out.println(matcher.group());
        }
    }
}
根据上面的需求,只需要把每个邮箱中的用户名爬取出来。
public class TextRegexDemo2 {
    public static void main(String[] args) {
         String data = "来学校进行学习Java,\n" +
                "电话:18512516758,18512508907\n" +
                "或者联系邮箱: boniu@itcast.cn\n" +
                "座机电话:01036517895,010-98951256\n" +
                "邮箱:bozai@itjava.cn,\n" +
                "邮箱2:dlei0009@163.com,\n" +
                "热线电话:400-618-9090 ,400-618-4000,\n" +
                "4006184000,4006189090\n";

        // 1、()是分组的意思,可以看出@前面一对小括号代表第一组,@后面的一对小括号,代表第二组
        String regex = "(\\w{2,30})@(\\w{2,20})(\\.\\w{2,10}){1,2}";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(data);
        while (matcher.find()){
            System.out.println(matcher.group(1));  //提取正则表达式规则匹配的第一对小括号里面的内容
        }

    }

//boniu
//bozai
//asei0009
}
根据下面的信息,爬取所有进入系统的用户名
public class RegexDemo4 {
    public static void main(String[] args) {
        String data = "欢迎张狗蛋光临本系统!他删库并跑路欢迎李二狗子光临本系统!\" +\n" +
                "                \" 欢迎马六子光临本系统!它浏览了很多好看的照片!欢迎夏洛光临本系统!他在六点钟送出了一个嘉年华!";

        String regex = "欢迎(.+?)光临";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(data);
        while (matcher.find()){
            //把爬到的信息提取出来
            String group = matcher.group(1);//爬取内容中的第一组
            System.out.println(group);
        }
    }
}

使用正则表达式替换和分割内容:
  • public String[] split(String regex)  按照正则表达式匹配的内容进行分割字符串,反回一个字符串数组。

  • public String replaceAll(String regex,String newStr)  按照正则表达式匹配的内容进行替换

案例一:

// 需求1:请把 古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴,中间的非中文字符替换成 “-”
public class RegexDemo5 {
    public static void main(String[] args) {
        // 需求1:请把 古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴,中间的非中文字符替换成 “-”
        String s1 = "古力娜扎ai8888迪丽热巴99fafas9aa5566马尔扎哈fbbADFFfsfs42425卡尔扎巴";
        String result = s1.replaceAll("\\w+", "-");
        System.out.println(result);
    }
}

案例二 

// 某语音系统,收到一个口吃的人说的“我我我喜欢编编编编编编编编编编编编程程程!”,需要优化成“我喜欢编程!”。
   String s2 = "我我我喜喜欢编编编程程";
        String result2 = s2.replaceAll("(.)\\1+", "$1");
        System.out.println(result2);

案例三:

请把 古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴,中的人名获取出来。
     String s3 = "古力娜扎ai8888迪丽热巴99fafas9aa5566马尔扎哈fbbADFFfsfs42425卡尔扎巴";
        String[] name = s3.split("\\w+");
        System.out.println(Arrays.toString(name));

效果:

java中的异常:

认识异常:

异常就是代表程序出现问题。

1,编译错误

2,运行时错误

3,逻辑错误

异常的结构:

所有异常类都有一个共同的祖先 Throwable(可抛出)

Throwable:有两个重要的子类,Exception(异常)和Error(错误)。异常和错误的区别是:异常能被程序本身可以处理,错误是无法处理。

Error(错误)

是程序本身可以处理的错误,表示运行应用程序中较为严重的错误。

Exception(异常)

是程序本身可以处理的异常。Exception 类有一个重要的子类 RuntimeException。

exception异常的分类:

它分为编译时异常和运行时异常

  • 运行时异常:RuntimeException及其子类,编译阶段不会出现错误提醒,运行时出现的异常(如:数组索引越界异常)
  • 编译时异常:编译阶段就会出现错误提醒的。(如:日期解析异常)

public class ExceptionDemo1 {
    public static void main(String[] args) throws ParseException {
        //运行时异常 RunTimeException
        int[] arr = {12,23,43};
        //System.out.println(arr[3]);  //出现索引下标越界异常 ArrayIndexOutOfBoundsException

        String name = null;
       // System.out.println(name.toString());
       // System.out.println(name.length());  //空指针异常 NullPointerException

        /**
         * 编译时异常,用来提醒我们这个代码很容易出现错误
         */

        String str = "2023-11-12 15:09:12";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf.parse(str);  //这里就会出现编译时异常
        System.out.println(date);

    }

}

public class ExceptionDemo2 {
    public static void main(String[] args) {
        System.out.println("开始");
     //   divide(6,2);
            try {
                divide(10,0);
                System.out.println("代码成功运行");
            } catch (Exception e) {
                System.out.println("系统出现了异常:"+e);
            }
        System.out.println("结束");
    }

    public static void divide(int a,int b){
        if (b == 0){
            throw new RuntimeException("b(除数不能为 0)");
        }
        System.out.println(a / b);
    }
}
public class ExceptionDemo3 {
    public static void main(String[] args) {
        while (true) {
            try {
                System.out.println("商品定价是:"+getPrice());
                break;
            } catch (Exception e) {
                System.out.println("你输入的价格有问题,请重新输入");
            }
        }
    }

    public static double getPrice(){
        System.out.println("请输入你的商品定价:");
        Scanner sc = new Scanner(System.in);
        double price = sc.nextDouble();
        return price;
    }
}
final和finally和finallize的区别:

final为关键字

finalize()为方法

finally()为区块标记,用于try语句中

作用:

1,final 用于标识常量的关键字,final 标识的关键字存储在常量池中
2,finalize()方法在Object中进行了定义,用于在对象“消失”时,由JVM进行调用用于对对象 进行垃圾回收,类似于C++中的析构函数。
3,finally{}用于标识代码块,与try{ }进行配合,不论try中的代码执行完或没有执行完(这里指有异常),该代码块之中的程序必定会进行。

自定义异常:
自定义编译时异常:
  • 继承Exception
  • 重写父类构造器

首先我们先写一个SdeAgeException自定义的异常类,然后在写一个SdeAgeExceptionTest的测试类


//继承Exception类,重写它的构造方法
public class SdeAgeException extends Exception{
    public SdeAgeException() {
        super();
    }

    public SdeAgeException(String message) {
        super(message);
    }
}

测试类:

public class SdeAgeExceptionTest {
    public static void main(String[] args) throws SdeAgeException {
        System.out.println("开始。。。");
        addAge(150);
        System.out.println("结束。。。");

    }

    public static void addAge(int age) throws SdeAgeException {
        if (age <=0 || age >= 150){
            //可以发现 这一行出现了很明显的报错提示,那我们就抛出异常,这是编译时异常。
            throw new SdeAgeException("age must be 1 -150 your age is"+age);
        }else {
            System.out.println("年龄添加成功");
        }
    }
}

效果图:

自定义运行时异常:
  • 继承RuntimeException
  • 实现父类的构造器

我们先定义一个SdeAgeRunTimeException类,然后在创建一个SdeAgeRunTimeExceptionTest的测试类。

public class SdeAgeRunTimeException extends RuntimeException{
    public SdeAgeRunTimeException() {
        super();
    }

    public SdeAgeRunTimeException(String message) {
        super(message);
    }
}

Test测试类:

public class SdeAgeRunTimeExceptionTest {
    public static void main(String[] args) {
        System.out.println("开始。。。");
            addAge(157);
        System.out.println("结束。。。");
    }

    public static void addAge(int age){
        if (age <= 0 || age >= 150){
            throw  new SdeAgeRunTimeException("age must be 1 -150 your age is"+age);
        }else {
            System.out.println("年龄添加成功");
        }
    }
}

效果:

java中异常处理的机制:

捕获异常,抛出异常。

抛出异常:throw/throws

throw方法内部抛出异常,一般和try-catch一起使用

throws 方法后抛出

注意:

throw和throws都会把异常问题抛给主程序

捕获异常——try-catch-finally

语法:

try{
    //可能出现错误的代码块
}catch(){  //捕获可能出现的异常
        //代码块
}finally{
    //注定要运行的出口
}


public class ExceptionDemo4 {
    public static void main(String[] args) {
        try {
            testA();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    public static void testA() throws FileNotFoundException, ParseException {
        testB();
        InputStream is = new FileInputStream("D://dog.png");
    }

    private static void testB() throws ParseException {
        String s = "2023-11-12 11:45:19";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = sdf.parse(s);
        System.out.println(d);
    }
}

我们会发现,通过throw抛出异常,底层的异常抛出给外层,最外层中捕获处理。我们可以看出,主调方法的try-catch中出现了太多的catch,要是太多我们肯定就记不住了。不如直接写成Exception

 try {
            testA();
        }  catch (Exception e) {
            e.printStackTrace();
        }

java中的泛型:

认识泛型:
  • 定义类,接口,方法时,同时声明了一个或者多个类型变量:如(<E>)称为泛型类,泛型接口,泛型方法。它们统称为泛型。
  • 作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力,这样可以避免强制类型转换,以及可能出现的异常。

泛型的本质:把具体的数据类型作为参数传递给类型变量。

泛型类:

修饰符 class 类名(类型变量,类型变量){

}

public class 

ArrayList<E>{}

注意:泛型变量建议使用大写的英文字母,常用的有:E T K V


public class GenericDemo1 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();  //没有添加泛型,可以传递任意类型的数据
        list.add("daoen1");
        list.add(12);
        list.add(true);
        list.add('A');
        System.out.println(list);

        System.out.println("---------------");
        ArrayList<String> list1 = new ArrayList<>(); //泛型是 String,只能接收String类型的数据
        list1.add("sundaoen");
        list1.add("javaproject");
        list1.add("html+css");
        for (int i = 0; i < list1.size(); i++) {
            String s = list1.get(i);
            System.out.println(s);
        }
    }
    
}
泛型接口:

修饰符 interface 接口名 (类型变量,类型变量...)

public interface Dog<E>{}

我们先自定义一个泛型接口:Data

public interface Data<E> {
    void  add(E e);
    boolean delete(E e);
    boolean update(E e);
    E getById(int id);
}

定义Student类:

public class Student {

}

定义Teacher类:

public class Teacher{

}

定义学生StudentDao类:实现泛型接口Data

public class StudentDao implements Data<Student>{
    @Override
    public void add(Student student) {

    }

    @Override
    public boolean delete(Student student) {
        return false;
    }

    @Override
    public boolean update(Student student) {
        return false;
    }

    @Override
    public Student getById(int id) {
        return null;
    }
}

定义TeacherDao实现Data泛型接口类:

public class TeacherDao implements Data<Teacher>{
    @Override
    public void add(Teacher teacher) {

    }

    @Override
    public boolean delete(Teacher teacher) {
        return false;
    }

    @Override
    public boolean update(Teacher teacher) {
        return false;
    }

    @Override
    public Teacher getById(int id) {
        return null;
    }
}

定义测试类:

public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        StudentDao stuDao = new StudentDao();
        stuDao.add(student);
        stuDao.delete(student);
        stuDao.getById(1);
        stuDao.update(student);
        System.out.println("-------------------------");
        Teacher teacher = new Teacher();
        TeacherDao tDao = new TeacherDao();
        tDao.add(teacher);
        tDao.delete(teacher);
        tDao.getById(1);
        tDao.update(teacher);
    }
}
泛型方法:

修饰符 (类型变量,类型变量...) 返回值类型 方法名(形参列表){}

public static <E> void test(E e){}

public class GenericDemo1 {
    public static void main(String[] args) {
        Integer[] age = {13,23,54,65,43};
        printArr(age);

        String[] names = {"三张","发的","时尚大方"};
        printArr(names);
        Integer max = getMax(age);
        String max1 = getMax(names);
    }

    public static <E> void printArr(E[] arr){

    }

    public static <E> E getMax(E[] arr){
        return null;
    }
}
通配符:

就是 "?" ,可以在使用泛型的时候代表一切类型, E T K V 是在定义泛型的时候使用

泛型的上下限:

泛型的上限: ?extend 一个父类 ?能接收的必须是这个父类(比如Car)或者其子类

泛型的下限:?super 一个父类  ?能接收的必须是比如(Car)或者其父类

public class GenericDemo2 {
    public static void main(String[] args) {
      //  ArrayList<Cat> cats = new ArrayList<Cat>();
        ArrayList<Cat> cats = new ArrayList<>();  //因为左边已经写好了,所以右边的泛型不需要在指定类型了。
        cats.add(new Cat());
        cats.add(new Cat());
        cats.add(new Cat());
        eat(cats);
        System.out.println("----------------------");
        ArrayList<Dog> dogs = new ArrayList<>();
        dogs.add(new Dog());
        dogs.add(new Dog());
        dogs.add(new Dog());
        eat(dogs);
    }

// Java提供了泛型上下限,约束?的具体类型。
        //    ? extends Animal : 上限: ? 必须是Animal的子类,顶多是Animal
        //    ? super Animal : 下限: ? 必须是Animal的父类,至少是Animal

    public static void eat(ArrayList<? extends Animal> animals ){
        
    }
}

class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
泛型的擦除问题和注意事项:
  • 泛型是工作在编译阶段的,一旦程序编译成class文件,class文件中就不存在泛型了,这就是泛型擦除。 泛型不能直接支持基本数据类型,只能支持对象类型(引用数据类型)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值