Java 学习笔记

发布时间:2024年01月17日

多态【面向对象编程的三大特征之一(继承、多态)】

多态

多态分为对象多态和行为多态【其实就是一种现象】
对象多态——意思就是,一个变量,它可以指向不同的对象【在继承的情况下,父对象可以指向一个子类型的变量】
行为多态——意思就是,一个父类型的变量,可以根据其实际指向的变量类型来判断运行哪种类型的方法【也即编译时看左边,运行时看右边】

final关键字【表示最终的意思】

  • 修饰类——该类不能被继承
  • 修饰变量——只能赋值一次 static final 修饰的变量称为常量【常量通常是大写】
  • 修饰方法——不能被重写

模板方法设计模式【抽象类的应用场景】

为了减少重复代码的编写
建议用final关键字修饰模板方法

接口interface

接口里只能有成员变量(默认为常量)和成员方法(抽象方法
一个类可以实现多个接口;与继承不同【extends】,只能继承一个

修饰符 class 实现类名 implements 接口1,接口2,接口3,...{
}

内部类

类中的五大成分

成员变量、内部类、构造器、方法、代码块

内部类

  • 成员内部类

创建格式【先创建外部类的对象再创建内部类的对象】
image.png

  • 静态内部类

由外部类自己持有
image.png
创建格式【直接用外部类.内部类来创建对象】
image.png
静态内部类只能访问外部类的静态成员【道理很简单,因为静态类可以不创建对象就访问,如果静态内部类可以访问外部类的实例成员变量,则会报错】

  • 匿名内部类

所谓匿名内部类的意思就是没有名字
创建格式
image.png
该类会创建一个子类对象,也即Java会自己创建一个【类或接口】的子类(用extends)。
适用场景
当一个方法的参数是一个接口类对象时,如果要调用该方法,则需要用匿名内部类来创建一个接口对象。

枚举类

image.png

泛型

image.png
image.png
注:

  1. 泛型发生在编译阶段,一旦编译为class文件,泛型就不存在了——泛型擦除
  2. 泛型只支持对象类型,不支持基本数据类型

重写(Override)和重载(Overload)的区别

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求,不能根据返回类型进行区分。

基本数据类型

image.png
image.png
包装类和基本数据类型可以自动装箱和自动拆箱

StringBuilder 和StringBuffer

StringBuilder是线程不安全的,StringBuffer是线程安全的

Lambda表达式

image.png
注意:只能用于函数式接口,也即该接口中只有一个函数
image.png

方法引用【为了简化lambda表达式】

静态方法引用

类名::静态方法
使用场景:
如果某个Lambda表达式里只是调用一个静态方法,并且前后参数的形式一致,就可以用静态方法引用

代码示例
package com.lidiang.reference1;

import java.util.Arrays;
import java.util.Comparator;

public class StacticReference {
    public static void main(String[] args) {
        Student[] students = new Student[5];
        students[0] = new Student("A",88);
        students[1] = new Student("Lily",12);
        students[2] = new Student("Alice",54);
        students[3] = new Student("God",108);
        students[4] = new Student("Bob",68);
        // 1.lambda表达式的标准写法
        //        Arrays.sort(students, new Comparator<Student>() {
        //            @Override
        //            public int compare(Student o1, Student o2) {
        //                return o1.getAge()-o2.getAge();
        //            }
        //        });

        // 2.简写,当参数列表与重写函数的参数列表相同时,可以省略到如下形式
        //        Arrays.sort(students, (o1, o2)-> {
        //                return o1.getAge()-o2.getAge();
        //            }
        //        );
        // 3.再简写,此时还可以直接把return和大括号也省略了
        //        Arrays.sort(students, (o1, o2)-> o1.getAge()-o2.getAge());
        // 4.静态方法,这里省略了return和大括号,且调用的是静态方法
        Arrays.sort(students, (o1, o2)-> CompareStatic.compare(o1,o2));
        // 5.静态方法引用
        Arrays.sort(students, CompareStatic::compare);
        System.out.println(Arrays.toString(students));
    }


}

其中静态方法所在的类描述如下:

package com.lidiang.reference1;

public class CompareStatic {
    public static int compare(Student o1,Student o2){
        return o1.getAge()-o2.getAge();
    }
}

学生类如下:

package com.lidiang.reference1;

public class Student {
    String name;
    int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

实例方法引用

类名::实例方法
适用场景:
如果某个Lambda表达式里只是调用一个实例方法,并且前后参数的形式一致,就可以用实例方法引用

代码示例
package com.lidiang.reference1;

import java.util.Arrays;
import java.util.Comparator;

public class StacticReference {
    public static void main(String[] args) {
        Student[] students = new Student[5];
        students[0] = new Student("A",88);
        students[1] = new Student("Lily",12);
        students[2] = new Student("Alice",54);
        students[3] = new Student("God",108);
        students[4] = new Student("Bob",68);
        // 1.lambda表达式的标准写法
//        Arrays.sort(students, new Comparator<Student>() {
//            @Override
//            public int compare(Student o1, Student o2) {
//                return o2.getAge()-o1.getAge();
//            }
//        });

          // 创建一个比较对象
        CompareStatic cp = new CompareStatic();
          // 2.调用该对象的实例方法进行sort
//        Arrays.sort(students,(o1,o2)->cp.comparedes(o1,o2));

         // 3.实例方法引用
        Arrays.sort(students,cp::comparedes);
        System.out.println(Arrays.toString(students));
    
}

此时的实例方法如下:

package com.lidiang.reference1;

public class CompareStatic {
    // public static int compare(Student o1,Student o2){
    //     return o1.getAge()-o2.getAge();
    // }

    public int comparedes(Student o1,Student o2){
        return o2.getAge()-o1.getAge();
    }
}

特殊类引用

不太懂,感觉用的不多

构造器引用

类名::new
适用场景:
如果某个Lambda表达式里只是在创建对象,并且前后参数情况一致,就可以使用构造器引用

代码示例
package com.lidiang.reference2;

import com.lidiang.reference1.Student;

public class NimingTest {
    public static void main(String[] args) {
        // 1.创建一个匿名内部类
//        CreateStudent cs = new CreateStudent() {
//            @Override
//            public Student Create(String name, int age) {
//                return new Student(name,age);
//            }
//        };

        // 2.简化后
//        CreateStudent cs =(name,age)->new Student(name,age);

        // 3.构造器引用;注意,这里的类::new中的类指的是被创建的类名,在这里指的是Student
        CreateStudent cs =Student::new;
        Student cc = cs.Create("小明",56);
        System.out.println(cc);
    }
}

// 声明一个创建对象的接口
interface CreateStudent{
    Student Create(String name,int age);
}

正则表达式

匹配正则表达式的方法

String matches(String regex)
其中regex的书写规则如下:
image.png

正则表达式的应用

1 查找

该功能利用正则表达式regex,模式化的对字符串文本进行提取信息。
主要有以下步骤:
a. 编写正则表达式regex
b. 确定待提取文本string
c. 创建Pattern对象
d. 创建Matcher对象
e. 用matcher.find进行提取,用matcher.group获取提取出的信息
例子如下:

package com.lidiang.zhengze;

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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

        // 待查找的字符串
        String string = "移动号码:18985686359" +
                "QQ: 7876959412@qq.com    热线电话:400-610-1360 4006101360 400610-1360";
        // 带匹配的正则式
        String regex = "(1[3-9]\\d{2,9})|(\\w{2,}@\\w{2,7}(\\.\\w{3,}){1,2})|(4\\d{2,5}(-?\\d{3,6}){2})";

        Pattern pattern = Pattern.compile(regex);

        Matcher matcher = pattern.matcher(string);

        while(matcher.find()){
            System.out.println(matcher.group());
        }
//        matchphone();
    }

    // 用正则式匹配字符串,判断字符串是否正确
    static void matchphone() {
        while (true) {
            System.out.println("请输入您的电话号码:");
            Scanner sc = new Scanner(System.in);
            String string = sc.next();
            boolean out = string.matches("1[3-9]\\d{2,9}");
            if (out) {
                System.out.println("号码正确~~");
            } else {
                System.out.println("号码错误~~");
            }
        }
    }
}

2 替换指定文本

该功能主要利用String的实例方法replaceALL
例子如下:

package com.lidiang.zhengze;

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

        // 用正则表达式来匹配字段并替换
        String st1 = "留学生sjisds4445女jisjisjd5889889小兰sjskdjas华中科技大学硕士";
        System.out.println(st1.replaceAll("\\w+", ","));

        // 用正则表达式去除多余的字符
        String st2 = "我我我我我我爱爱爱爱爱爱爱爱学学学学学学学学学学习习";
        System.out.println(st2.replaceAll("(.)\\1+", "$1"));
    }

}

文章来源:https://blog.csdn.net/qq_45756448/article/details/135603566
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。