Bootstrap

面向对象(高级进阶)

面向对象(高级进阶)

学习地址——黑马程序员

代码块

  • 代码块是类的5大成分之一(成员变量、构造器、方法、代码块、内部类

代码块的分类:静态代码块、实例代码块

  • 静态代码块:
    • 格式:tatic{}
    • 特点:类加载时自动执行,由于类只会加载一次,所以静态代码块也只会执行一次。
    • 作用:完成类的初始化,例如:对静态变量的初始化赋值。

代码实例

package com.itheimaoop.oopdemo01;

import java.util.Arrays;

public class CodeDemo1 {
    public static String SchoolName;
    public static String[] cards = new String[54];
    //静态代码块:用static修饰,属于类,与类一起优先加载,自动执行一次
    //基本作用:可以完成对类的静态化资源的初始化
    static{
        System.out.println("=====静态代码块执行了=====");
        SchoolName = "M-Freedom";
        cards[0] = "A";
        cards[1] = "2";
        cards[2] = "3";
        cards[3] = "4";
    }
    public static void main(String[] args) {
        System.out.println("=====main方法执行了=====");
        System.out.println(SchoolName);
        System.out.println(cards[0]);
        System.out.println(cards[1]);
        System.out.println(Arrays.toString(cards));
    }
}
  • 实例代码块
    • 格式:{}
    • 特点:每次创建对象时,执行实例代码块,并在构造器前执行。
    • 作用:和构造器一样,都是用来完成对象的初始化的,例如:对实例变量进行初始化赋值。

内部类

如果一个类定义在一类的内部,这个类就是内部类。

场景:当一个类的内部,包含了一个完整的事物,且这个是事物没有必要单独设计时,就可以把这个事物设计成内部类。

public class Car{
    //内部类
    public class Engine{
    }
}

成员内部类

  • 就是类中的一个普通成员,类似之前学过的普通的成员变量、成员方法。
public class Outer{
    //成员内部类
    public class Inner{
    }
}

代码实例

成员内部类

package com.itheimaoop.innerclass;

public class Outer {
    //成员内部类
    public class Inner {
        private String name;
        public void show(){
            System.out.println("成员内部类");
        }
        //无参构造器
        public Inner(){
            System.out.println("成员内部类无参构造器执行了");
        }
        //有参构造器
        public Inner(String name){
            System.out.println("成员内部类有参构造器执行了");
        }
        //getter和setter方法
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
}

成员内部类创建对象的语法格式

package com.itheimaoop.innerclass;

public class InnerClassDemo1 {
    public static void main(String[] args) {
        //成员内部类创建对象的格式
        //外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
        Outer.Inner oi = new Outer().new Inner();
        oi.show();
        oi.setName("M-Freedom");
        System.out.println(oi.getName());
    }
}
  • 成员内部类访问外部类成员的特点(拓展)
      1. 成员内部类可以直接访问外部类的静态成员,也可以直接访问外部类的实例成员以及实例方法;
      2. 成员内部类的实例方法,可以直接拿到当前寄生对象的外部类对象,语法格式为:外部类.this

代码实例

package com.itheimaoop.innerclass;

public class InnerClassDemo1 {
    public static void main(String[] args) {
        //调用成员内部类方法
        People.Heart ph = new People().new Heart();
        ph.show();
    }
}

class People{
    private int HeartBeat = 60;
    //成员内部类
    public class Heart {
        int HeartBeat = 180;
        //成员内部类方法
        public void show(){
            int HeartBeat = 80;
            System.out.println(HeartBeat); //80
            System.out.println(this.HeartBeat);//180
            System.out.println(People.this.HeartBeat);//60
        }
    }
}

静态内部类

  • 有static修饰的内部类,属于外部类自己持有。
public class Outer{
    //静态内部类
    public static class Inner{
        
    }
}
外部类.内部类名 对象名 = new 外部类.内部类(...);
Outer.Inner oi = new Outer.Inner();

代码实例

静态内部类

package com.itheimaoop.innerclass2;
//外部类
public class Outer {
    private static int age;
    //静态内部类
    public static class Inner{
        private String name;
        public void show(){
            System.out.println("=====静态内部类执行了=====");
            System.out.println(Outer.age);
        }
        //静态内部类构造器
        public Inner(){
            System.out.println("=====静态内部类构造器执行了=====");
        }
        //静态内部类有参构造器
        public Inner(String name){
            System.out.println("=====静态内部类有参构造器执行了=====");
        }
        //getter和setter方法
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    //外部类getter和setter方法
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

静态内部类创建对象的语法格式

package com.itheimaoop.innerclass2;

public class InnerClassDemo1 {
    public static void main(String[] args) {
        //静态内部类属于外部类自己持有
        //外部类名.静态内部类名 对象名 = new 外部类名称.静态内部类名称();
        Outer.Inner oi = new Outer.Inner();
        Outer outer = new Outer();
        outer.setAge(28);
        System.out.println(outer.getAge());
        oi.setName("M-Freedom");
        System.out.println(oi.getName());
    }
}

局部内部类(了解)

局部内部类是定义在在方法中、代码块中、构造器等执行体中。

public class Test{
    public static void main(String[] args) {
        
    }
    public static void go(){
        class A{
            
        }
        abstract class B {
        
    	}
        interface C {
            
        }
    }
    
}

匿名内部类(重点)

匿名内部类的认识
  • 一种特殊的局部内部类
  • 所谓匿名:指的是程序员不需要为这个类声明名字,默认有个隐藏的名字。
new 类或接口(参数值...){
    类体(一般是方法重写);
}
new Animal(){
    @Override
    public void cry(){
    }
}
  • 特点:
    • 匿名内部类本质就是一个子类,并会立即创建出一个子类对象。
  • 作用:
    • 用于更方便的创建一个子类对象。

代码实例

匿名内部类

package com.itheimaoop.innerclass3;

public class Test {
    public static void main(String[] args) {
        //目标:认识匿名内部类,搞清楚基本作用
        //使用多态创建对象Cat
        //Animal cat = new Cat();
        //cat.cry();
        //使用匿名内部类创建对象Cat

        //匿名内部类本质是一个子类,同时会立即构建一个子类对象
        Animal cat2 = new Animal() {
            //重写抽象方法cry()
            @Override
            public void cry() {
                System.out.println("🐱是喵喵的叫~~~~~~~~~~");
            }
        };
        cat2.cry();
    }
}
//匿名内部类本质就是一个子类,并会立即创建出一个子类对象。
/*
匿名内部类$1.class文件
package com.itheimaoop.innerclass3;

final class Test$1 extends Animal {
    Test$1() {
    }

    public void cry() {
        System.out.println("\ud83d\udc31是喵喵的叫~~~~~~~~~~");
    }
}
 */

抽象类—父类

package com.itheimaoop.innerclass3;
//定义抽象类
public abstract class Animal {
    public abstract void cry();
}
匿名内部类的常见使用形式
  • 匿名内部类:通常作为一个对象参数传输给方法。

代码实例——需求:学生、老师参加游泳比赛

  • 匿名内部类:对象回调
package com.itheimaoop.innerclass3;

import javax.rmi.CORBA.Util;

public class Test2 {
    public static void main(String[] args) {
        //匿名内部类的使用形式(语法):通常作为一个对象参数传输给方法。
        //需求:学生、老师参加游泳比赛

        //传统方法:用 Student 和 Teacher 对象来调用 StartSwim 方法
        Swim student = new Student();
        startSwim(student);
        Swim teacher = new Teacher();
        startSwim(teacher);

        System.out.println("==========================================================================");
        //匿名内部类方法(对象回调)
        Swim s1 = new Swim() {
            //重写接口方法
            public void swimming() {
                System.out.println("学生游泳真厉害~~~~~");
            }
        };
        startSwim(s1);
        Swim s2 = new Swim() {
            //重写接口方法
            public void swimming() {
                System.out.println("老师游泳不见了~~~~~");
            }
        };
        startSwim(s2);

    }

    //传统方法:设计一个方法,可以接收老师和学生开始游泳
    public static void startSwim(Swim s){
        System.out.println("开始游泳~~~~~");
        s.swimming();
        System.out.println("游泳结束~~~~~");
    }
}

//定义Student类实现接口
class Student implements Swim{
    //重写接口方法
    @Override
    public void swimming() {
        System.out.println("学生游泳差点被淹死~~~~~");
    }
}
//定义Teacher类实现接口
class Teacher implements Swim{
    //重写接口方法
    @Override
    public void swimming() {
        System.out.println("老师游泳很健康~~~~~");
    }
}

//定义一个Swim接口
interface Swim{
    // 接口中的方法默认是 public abstract 的,无需显式声明 public
    void swimming(); //游泳方法
}
匿名内部类的应用场景
  • 调用别人提供的方法实现需求时,这个方法正好可以让我们传输一个匿名内部类对象给其使用。

案例1——创建一个登录窗口,窗口上只有一个登录按钮(GUI界面编程部分)

package com.itheimaoop.innerclass3;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Test3 {
    public static void main(String[] args) {
        //明白匿名内部类的使用场景
        //需求:创建一个登录窗口,窗口上只有一个登录按钮

        // 创建一个名为“登录窗口”的JFrame实例
        JFrame win = new JFrame("登录窗口");
        // 设置窗口的大小为300x200像素
        win.setSize(300, 200);
        // 将窗口位置设置为屏幕中心
        win.setLocationRelativeTo(null);
        // 设置窗口关闭操作,当用户关闭窗口时退出应用程序
        win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 创建一个新的JPanel实例,作为窗口的一部分,用于承载其他组件
        JPanel panel = new JPanel();
        // 将创建的面板添加到窗口中,使其能够在界面上显示
        win.add(panel);

        // 创建一个带有“登录”标签的JButton实例,用于触发登录操作
        JButton btn = new JButton("登录");
        // 将创建的按钮添加到面板上,使其能够在界面上显示并供用户交互
        panel.add(btn);

        //java要求必须给这个按钮添加一个点击事件监听器,这样就可以监听用户的点击操作,就可以做出反应。
        //开发中不是我们要主动去写的匿名内部类,而使用是别人的功能的时候,别人可以让我们写一个匿名内部类,我们才会写!
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("登录成功!");
            }
        });

        // 设置窗口可见,以便用户可以与界面上的组件进行交互
        win.setVisible(true);


    }
}
//class LoginListener implements ActionListener {
//    @Override
//    public void actionPerformed(ActionEvent e) {
//        System.out.println("用户点击了登录按钮");
//    }
//}

案例2——使用comparator接口的匿名内部类实现对数组进行排序

Test

package com.itheimaoop.innerclass3;

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

public class Test4 {
    public static void main(String[] args) {
        // 完成给数组排序,理解其中匿名内部类的用法
        // 准备一个学生类型的数组,存放6个学生对象
        Student2[] students = new Student2[6];
        students[0] = new Student2("张三丰", 80, 185, "男");
        students[1] = new Student2("张无忌", 30, 190, "男");
        students[2] = new Student2("赵敏", 23, 165, "女");
        students[3] = new Student2("周芷若", 25, 166, "女");
        students[4] = new Student2("张三", 80, 140, "男");
        students[5] = new Student2("赵四", 27, 170, "女");

        //需求:按照年龄大小进行排序;调用sun公司写好的API直接对数组进行排序
        // public static <T> void sort(T[] a, Comparator<? super T> c)
        //               参数一:需要排序的数组;
        //               参数二:需要给sort方法声明一个Comparator比较器对象(指定排序规则);
        // sort方法内部会调用匿名内部类中的compare方法,对数组中的两个对象进行两两比较,从而实现排序
        Arrays.sort(students, new Comparator<Student2>() {
            @Override
            public int compare(Student2 o1, Student2 o2) {
                // 指定排序规则
                // 如果你认为左边对象 大于 右边对象,返回正数;
                // 如果你认为左边对象 小于 右边对象,返回负数;
                // 如果你认为左边对象 等于 右边对象,返回0;
                //return o1.getAge() - o2.getAge(); // 按照年龄升序!
                // return o2.getAge() - o1.getAge(); // 按照年龄降序!
                return o1.getHeight() - o2.getHeight();

//                if (o1.getAge() > o2.getAge()) {
//                    return 1;
//                } else if (o1.getAge() < o2.getAge()) {
//                    return -1;
//                }
//                return 0;
            }
        });


        //遍历数组中的学生对象并输出
        for (int i = 0; i < students.length; i++) {
            Student2 s = students[i];
            System.out.println(s);
        }
    }
} 

Student类

package com.itheimaoop.innerclass3;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data //自动生成getter setter方法
@NoArgsConstructor //自动生成无参构造
@AllArgsConstructor //自动生成有参构造

public class Student2 {
    //姓名 年龄 身高 性别
    private String name;
    private int age;
    private int height;
    private String sex;

}

函数式编程

Lambda

函数式编程:此”函数”类似于数学中的函数(强调做什么),只要输入的数据一致返回的结果也是一致的。

Java中的函数:Lambda表达式

  • 使用Lambda函数替代某些匿名内部类对象,从而让程序代码更简洁,可读性更好。

  • Lambda表达式

    • JDK-8新增的一种语法格式,表示函数。
    • 可以用于替换默写匿名内部类对象,从而使程序更简洁,可读性更好。
(被重写方法的形态列表) -> {
    被重写方法体的代码。
}
  • 函数式接口
    • 有且仅有一个抽象方法的接口
package com.itheimaoop.lambda;

public class LambdaDemo1 {
    public static void main(String[] args) {
        // 目标:认识Lambda表达式,搞清楚其基本作用

        // 匿名内部类调用Animal对象
        Animal a = new Animal() {
            @Override
            public void cry() {
                System.out.println("Animal cry");
            }
        };
        a.cry();

        // 错误示范:Lambda 表达式并不是可以简化全部的匿名内部类,Lambda只能简化函数式接口的匿名内部类!
//        Animal a1 = () -> {
//            System.out.println("Animal cry");
//        };
//        a1.cry();

        // 匿名内部类实现Swim接口
        Swim s = new Swim() {
            @Override
            public void swimming() {
                System.out.println("Swim swimming");
            }
        };
        s.swimming();

        // 使用Lambda表达式
        Swim s2 = () -> {
            System.out.println("Swim swimming");
        };
        s2.swimming();
    }
}

// 定义一个抽象类Animal
abstract class Animal {
    public abstract void cry();
}

// 定义一个接口
// 函数式接口:只能有一个抽象方法的接口
@FunctionalInterface // 声明为函数式接口的注解
interface Swim{
    void swimming();
}

注意:Lambda表达式只能替代函数式接口的匿名内部类!

lambda实战示例:

lamdba代码简化实例

package com.itheimaoop.lambda;

import com.itheimaoop.innerclass3.Student2;

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

public class LamdbaDemo2 {
    public static void main(String[] args) {
        // 完成给数组排序,理解其中匿名内部类的用法
        // 准备一个学生类型的数组,存放6个学生对象
        Student2[] students = new Student2[6];
        students[0] = new Student2("张三丰", 80, 185, "男");
        students[1] = new Student2("张无忌", 30, 190, "男");
        students[2] = new Student2("赵敏", 23, 165, "女");
        students[3] = new Student2("周芷若", 25, 166, "女");
        students[4] = new Student2("张三", 80, 140, "男");
        students[5] = new Student2("赵四", 27, 170, "女");

        // 代码简化--1
//        Arrays.sort(students, new Comparator<Student2>() {
//            @Override
//            public int compare(Student2 o1, Student2 o2) {
//                if (o1.getAge() > o2.getAge()) {
//                    return 1;
//                } else if (o1.getAge() < o2.getAge()) {
//                    return -1;
//                }
//                return 0;

        // 代码简化--2
//        Arrays.sort(students, (Student2 o1, Student2 o2) -> {
//            return o1.getAge() - o2.getAge(); // 按照年龄升序!
//        });

        // 代码简化--3
        Arrays.sort(students, (o1, o2) -> o1.getAge() - o2.getAge());


        //遍历数组中的学生对象并输出
        for (int i = 0; i < students.length; i++) {
            Student2 s = students[i];
            System.out.println(s);
        }
    }
}

方法引用

静态方法的引用
  • 类名::静态方法

使用场景:

  • 如果某个Lambda表达式里只是调用一个静态方法,并且“→”前后参数的形式一致,就可以使用静态方法引用。

代码实例

Test

package com.itheimaoop.method1reference;

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

public class Demo1 {
    public static void main(String[] args) {
        // 完成给数组排序,理解其中匿名内部类的用法
        // 准备一个学生类型的数组,存放6个学生对象
        Student2[] students = new Student2[6];
        students[0] = new Student2("张三丰", 80, 185, "男");
        students[1] = new Student2("张无忌", 30, 190, "男");
        students[2] = new Student2("赵敏", 23, 165, "女");
        students[3] = new Student2("周芷若", 25, 166, "女");
        students[4] = new Student2("张三", 80, 140, "男");
        students[5] = new Student2("赵四", 27, 170, "女");

        Arrays.sort(students, (o1, o2) -> o1.getAge() - o2.getAge());

        Arrays.sort(students, (o1, o2) -> Student2.compare(o1, o2));

        // 静态方法引用   类名::静态方法
        Arrays.sort(students, Student2::compare);

        //遍历数组中的学生对象并输出
        for (int i = 0; i < students.length; i++) {
            Student2 s = students[i];
            System.out.println(s);
        }
    }
}

Student class

package com.itheimaoop.method1reference;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data //自动生成getter setter方法
@NoArgsConstructor //自动生成无参构造
@AllArgsConstructor //自动生成有参构造

public class Student2 {
    //姓名 年龄 身高 性别
    private String name;
    private int age;
    private int height;
    private String sex;

    // 静态方法,把两个学生对象进行封装
    public static int compare(Student2 o1, Student2 o2) {
        return o1.getAge() - o2.getAge();
    }
}
实例方法的引用
  • 对象名::实例方法

使用场景:

  • 如果某个Lambda表达式里只是通过对象名称调用一个实例方法,并且“→”前后参数的形式一致,就可以使用实例方法引用。

代码实例

Test

package com.itheimaoop.method2reference;

import java.util.Arrays;

public class Demo {
    public static void main(String[] args) {
        // 完成给数组排序,理解其中匿名内部类的用法
        // 准备一个学生类型的数组,存放6个学生对象
        Student2[] students = new Student2[6];
        students[0] = new Student2("张三丰", 80, 185, "男");
        students[1] = new Student2("张无忌", 30, 190, "男");
        students[2] = new Student2("赵敏", 23, 165, "女");
        students[3] = new Student2("周芷若", 25, 166, "女");
        students[4] = new Student2("张三", 80, 140, "男");
        students[5] = new Student2("赵四", 27, 170, "女");

        // 按照身高进行排序
        Student2 s = new Student2();
        // 实例方法引用    对象名::实例方法
        // 前提:-> 前后参数的形式一致
        Arrays.sort(students, s::CompareHeight);

        // 静态方法引用   类名::静态方法
        Arrays.sort(students, Student2::compare);

        //遍历数组中的学生对象并输出
        // 前提:-> 前后参数的形式一致
        for (int i = 0; i < students.length; i++) {
            Student2 s1 = students[i];
            System.out.println(s1);
        }
    }
}

Student class

package com.itheimaoop.method2reference;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data //自动生成getter setter方法
@NoArgsConstructor //自动生成无参构造
@AllArgsConstructor //自动生成有参构造

public class Student2 {
    //姓名 年龄 身高 性别
    private String name;
    private int age;
    private int height;
    private String sex;

    // 静态方法,把两个学生对象进行封装
    public static int compare(Student2 o1, Student2 o2) {
        return o1.getAge() - o2.getAge();
    }

    // 实例方法
    public int CompareHeight(Student2 o1, Student2 o2) {
        return Double.compare(o1.getHeight(), o2.getHeight());
    }
}
特定类型方法的引用
  • 特定类的名称::方法

使用场景:

  • 如果某个Lambda表达式里只是调用一个特定类型的实例方法,并且前面参数列表中的第一个参数是作为方法的主调,后面的所有参数都是作为该实例方法的入参的,则此时就可以使用特定类型的方法引用。

代码实例

package com.itheimaoop.method3reference;

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

public class Demo {
    public static void main(String[] args) {
        // 目标:特定类型的方法引用
        // 需求:有一个字符串数组,里面有一些人的名字都是英文名字,请按照名字的首字母升序排序。
        String[] names = {"Tom", "andy", "judy", "Jerry", "Mike", "bob", "Jack", "Lucy", "Lily", "Angela"};

        // 把这个的数组按首字母进行排序
        // Arrays.sort(names);  // 默认按照首字母的编号升序排序
        // 要求: 忽略首字母的大小进行排序,需要指定规则
        Arrays.sort(names, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                // andy
                // Angela
                return o1.compareToIgnoreCase(o2); // 忽略大小写进行排序:compareToIgnoreCase
            }
        });

        // 优化:方法引用
        // Arrays.sort(names, (o1, o2) -> o1.compareToIgnoreCase(o2));
        Arrays.sort(names, (o1, o2) -> o1.compareToIgnoreCase(o2));
        // 特定类型方法引用
        Arrays.sort(names, String::compareToIgnoreCase);

        System.out.println(Arrays.toString(names));
    }
}

构造器引用
  • 类名::new

使用场景

  • 如果某个Lambda表达式里只是在创建对象,并且“→”前后参数情况一致,就可以使用构造器引用。

代码实例

package com.itheimaoop.method4reference;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

public class Demo {
    public static void main(String[] args) {
        // 构造器方法引用
        // 接口的匿名内部类对象
        CarFactory cf = new CarFactory(){
            // 重写接口方法
            public Car getCar(String name) {
                return new Car(name);
            }
        };

        CarFactory cf1 = name -> new Car(name);

        // 构造器引用 类名::new
        CarFactory cf2 = Car::new;

        Car c1 = cf.getCar("保时捷");
        System.out.println(c1.getName());
    }
}



interface CarFactory{
    Car getCar(String name);
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Car {
    private String name;
}

常用API

String

  • String代表字符串数据,它的对象可以封装字符串数据,并且提供了很多方法完成对字符串的处理。
String创建字符串对象的方式
  • 方式一:Java程序中所有字符串文字(例如“a, b, c”)都为此类对象。
String name = "小黑";
String schoolName = "黑马程序员";
  • 方式二:调用String类的构造器初始化字符串对象。
构造器说明
public String()创建一个空白字符串对象,不含有任何内容
public String(String Original)根据传入的字符串内容,来创建字符串对象
public String(char[] chars)根据字符串组的内容,来创建字符串对象
public String(byte[] bytes)根据字节数字的内容,来创建字符串对象
  • String创建字符串的区别

    • 只要是以方式写出的字符串对象,会存储到字符串常量池且相同内容的字符串只存储一份;
    • 通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。
  • String 提供的常用方法

方法名说明
public int length()获取字符串的长度返回(就是字符个数)
public char charAt(int index)获取某个索引位置处的字符返回
public char[] toCharArray():将当前字符串转换成字符数组返回
public boolean equals(Object anObject)判断当前字符串与另一个字符串的内容一样,一样返回true
public boolean equalsIgnoreCase(String anotherString)判断当前字符串与另一个字符串的内容是否一样 (忽略大小写)
public String substring(int beginIndex, int endIndex)根据开始和结束索引进行截取,得到新的字符串(包前不包后)
public String substring(int beginIndex)从传入的索引处截取,截取到末尾,得到新的字符串返回
public String replace(CharSequence target, CharSequence replacement)使用新值,将字符串中的旧值替换,得到新的字符串
public boolean contains(CharSequence s)判断字符串中是否包含了某个字符串
public boolean startsWith(String prefix)判断字符串是否以某个字符串内容开头,开头返回true,反之
public String[] split(String regex)把字符串按照某个字符串内容分割,并返回字符串数组回来

代码实例

package com.itheimaoop.string;

import java.util.Scanner;

public class StringDemo1 {
    public static void main(String[] args) {
        // 目标:掌握创建字符串对象,封装要处理的字符串数据,调用String提供的方法处理数据
        // 1.推荐方式一:直接“”创建字符串对象,封装字符串数据
        String name = "itcast";
        System.out.println(name);

        System.out.println(name.length()); // 处理字符串的方法

        // 方式二:通过构造器初始化对象
        String s = new String(); // 不推荐
        System.out.println(s); // 空字符串

        // 方式三:通过有参构造器初始化对象
        String s1 = new String("itcast"); // 不推荐
        System.out.println(s1);

        char[] chars = {'i', 't', 'c', 'a', 's', 't'};
        String s2 = new String(chars); // 字符数组转换为字符串
        System.out.println(s2);

        byte[] bytes = {97, 98, 99, 100, 101, 102};
        String s3 = new String(bytes); // 字节数组转换为字符串
        System.out.println(s3);

        System.out.println("===============================================");
        // 只有用""给出的字符串对象存放在字符串常量池中,相同内容只放一次
        String t1 = "abc";
        String t2 = "abc";
        System.out.println(t1 == t2);
        // new出来的对象,每次都创建一个对象,存放在堆中
        String t3 = new String("abc");
        String t4 = new String("abc");
        System.out.println(t3 == t4);

        System.out.println("===============================================");
        // 2.字符串对象可以调用String类提供的方法,对字符串进行操作
        // 示例:简易版登录系统
        String username = "admin";
        System.out.println("请输入登录名称:");
        Scanner scanner = new Scanner(System.in);
        String inputName = scanner.next();

        // 判断字符串是否相等,建议使用String提供的equals方法,不建议使用==,equals比较的是内容,==比较的是地址
        if (inputName.equals(username)) {
            System.out.println("登录成功");
        } else {
            System.out.println("登录失败");
        }

        // 截取字符串
        // 示例:截取字符串,隐藏手机号码中间四位
        String phone = "13812345678";
        System.out.println("请拨打电话:");
        Scanner sc = new Scanner(System.in);
        String inputPhone = sc.next();

        System.out.println("系统隐私保护,将以下列方式进行拨打!");
        String phone1 = phone.substring(0, 3) + "****" + phone.substring(7);
        System.out.println(phone1);

    }
}
常用API——开发验证码案例

AI+ 代码实例练习

写出大致思路,利用AI生成代码

package com.itheimaoop.string;

public class StringTest1 {
    public static void main(String[] args) {
        // 生成验证码

        System.out.println(getCode(4));
        System.out.println(getCode(6));

    }

    // 生成指定位数的验证码返回,验证码由数字和字母组成,字母包含大小写
    // 用String变量记住全部需要用到的字符

    // 1. 定义一个方法,返回一个验证码
    public static String getCode(int length) {
        // 2. 创建一个StringBuilder对象,用来拼接字符串
        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        // 3.定义一个变量用于记住验证码的随机字符
        String code = "";
        for (int i = 0; i < length; i++) {
            // 4. 获取随机索引
            int index = (int) (Math.random() * str.length()); // 获取随机数,取值范围为[0.0, 1.0) * str.length()
            // 5. 根据索引获取字符,并拼接
            code += str.charAt(index);
        }
        // 6. 返回验证码
        return code;
    }
}
ArrayList(常用API)
  • ArrayList属于集合

    • 集合是一种容器,用来装数据,类似于数组
  • ArrayList集合

构造器说明
public ArrayList()创建一个空的集合对象
  • 常用方法
常用方法名说明
public boolean add(E e)将指定的元素添加到此集合的末尾
public void add(int index,E element)在此集合中的指定位置插入指定的元素
public E get(int index)返回指定索引处的元素
public int size()返回集合中的元素的个数
public E remove(int index)删除指定索引处的元素,返回被删除的元素
public boolean remove(Object o)删除指定的元素,返回删除是否成功
public E set(int index,E element)修改指定索引处的元素,返回被修改的元素

AI+代码实例

package com.itheimaoop.string;

import java.util.ArrayList;

public class ArrayListDemo1 {
    public static void main(String[] args) {
        // 掌握ArrayList集合的使用
        // 创建ArrayList对象,代表一个集合容器
        ArrayList<String> list = new ArrayList<>(); // 泛型< >,指定集合中存储的数据类型
        // 添加数据
        list.add("java");
        list.add("python");
        list.add("c++");
        list.add("c#");
        list.add("php");
        System.out.println(list);
        // 查看数据
        System.out.println(list.get(0));
        System.out.println(list.get(1));
        System.out.println(list.get(2));
        System.out.println(list.get(3));
        System.out.println(list.get(4));
        // 遍历集合
        System.out.println("遍历集合开始了");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        System.out.println("==================================");
        // 删除数据
        // remove(int index) 删除指定索引位置的数据,并返回被删除的数据
        System.out.println(list.remove(0));
        System.out.println(list);
        // remove(Object o) 删除指定数据,并返回删除成功与否
        System.out.println(list.remove("c#"));
        System.out.println(list);
        // 修改数据
        list.set(0, "javaee");
        System.out.println(list);
        // 在指定位置插入数据go
        list.add(3, "go");
        System.out.println(list);
    }
}

GUI编程(Java应用比较少)

GUI界面编程

  • GUl,全称GraphicalUserInterface,是指图形用户界面
  • 通过图形元素(如窗口、按钮、文本框等)与用户进行交互
  • 与命令行界面(CLI)相比,GUI更加直观、友好

Java的GUI编程包

  • AWT (Abstract Window Toolkit)

    • 提供了一组原生的GUI组件,依赖于操作系统的本地窗口系统
  • Swing

    • 基于AWT,提供了更丰富的GUI组件,轻量级组件,不依赖于本地窗口系统
  • 常用的Swing组件

    • JFrame:窗口
    • JPanel:用于组织其他组件的容器
    • JButton:按钮组件
    • JTextField:输入框
    • JTable:表格
  • 常见的布局管理器

    • 布局管理器它们可以决定组件在容器中的布局方式,避免了手动设置每个组Layout Manager)件的位置和大小,从而简化了GUI设计过程。
  • 常见的布局管理器

    • FlowLayout
    • BorderLayout
    • GridLayout
    • BoxLayout
  • GUI事件处理

    • GUI编程中,事件的处理是通过事件监听器(EventListener)来完成的常用的事件监听器对象
    • 点击事件监听器 ActionListener
    • 按键事件监听器 KeyListener
    • 鼠标行为监听器 MouseListener
  • 事件的几种常见写法

    • 第1种:直接提供实现类,用于创建事件监听对象
    • 第2种:直接使用匿名内部类的对象,代表事件监听对象
    • 第3种:自定义窗口,让窗口对象实现事件接口

高级代码实例

Test

package com.itheimaoop.gui2;

import javax.swing.*;

public class Test3 {
    public static void main(String[] args) {
        // 目标:自定义一个登录界面,让界面对象本身也是事件监听器对象
        // JFrame是窗口对象
        LoginFrame lf = new LoginFrame(); // 创建一个登录窗口对象
        // 设置窗口可见
        lf.setVisible(true);
    }
}

LoginFrame 既作为 JFrame 的子类实现窗口登录界面;有作为接口 ActionListener的实现类 实现事件监听器

package com.itheimaoop.gui2;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

// 自定义一个登录界面
// 让窗口同时实现事件监听器接口
public class LoginFrame extends JFrame implements ActionListener {
    // 无参构造器
    public LoginFrame() {
        // 1.设置窗口标题
        this.setTitle("登录界面");
        // 2.设置窗口大小
        this.setSize(400, 300);
        // 3.设置窗口位置
        this.setLocationRelativeTo(null);
        // 4.设置窗口关闭操作
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 调用init方法
        init();
    }

    // 添加组件: 添加一个登录按钮和一个面板
    private void init(){
        // 添加一个登录按钮
        JButton jb = new JButton("登录");

        // 为登录按钮添加点击事件,实现类的匿名内部类
        jb.addActionListener(this);

        // 添加登录面板
        JPanel panel = new JPanel();
        this.add(panel); // 将面板添加到窗口中,this 表示当前窗口

        panel.add(jb); // 将按钮添加到面板中
    }

    // 重写接口方法
    public void actionPerformed(ActionEvent e) {
        JOptionPane.showConfirmDialog(this, "登录成功");  // this 表示当前窗口对象
    }
}
;