面向对象(高级进阶)
代码块
- 代码块是类的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());
}
}
- 成员内部类访问外部类成员的特点(拓展)
-
- 成员内部类可以直接访问外部类的静态成员,也可以直接访问外部类的实例成员以及实例方法;
- 成员内部类的实例方法,可以直接拿到当前寄生对象的外部类对象,语法格式为:外部类.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 表示当前窗口对象
}
}