一、代码块
1、静态代码块: 比main函数先执行
public class Test {
public static String[] cards = new String[5];
//使用静态代码块初始化数组,避免重复初始化
static {
cards[0] = "A";
cards[1] = "2";
cards[2] = "3";
cards[3] = "4";
cards[4] = "5";
}
public static void main(String[] args) {
System.out.println(Arrays.toString(cards));
}
}
2、实例代码块:new一个对象的时候才执行
public class Test2 {
public String[] directions = new String[4];
// 实例代码块
{
directions[0] = "N";
directions[1] = "S";
directions[2] = "E";
directions[3] = "W";
}
public static void main(String[] args) {
// 先执行了 System.out.println("-----main方法执行了----")
System.out.println("-----main方法执行了----");
System.out.println(new Test2().directions[0]);
}
}
二、 内部类
1、成员内部类
public class Outer {
public static String name = "Outer";
public static void test(){
System.out.println("test");
}
// 成员内部类:无static修饰,属于外部类的对象持有的
class Inner{
public String name = "Inner";
// 构造器:new一个对象的时候就会执行
public Inner() {
System.out.println("Inner()");
}
// 有参构造器
public Inner(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// show方法
public void show(){
System.out.println(name);
System.out.println(Outer.this);
// 访问外部类的属性
System.out.println(Outer.name);
// 调用外部类的方法
test();
}
}
}
// 应用,会依次打印出Inner()、Inner、com.oop.demo10.Outer@2f4d3709、Outer、test
public class Test3 {
public static void main(String[] args) {
Outer.Inner inner = new Outer().new Inner();
inner.show();
}
}
2、静态内部类
public class OuterTwo {
public static String name = "Outer2";
private int age; // 私有成员变量
// 静态内部类
public static class Inner {
public String name = "Inner2";
public void show() {
System.out.println(name);
System.out.println(OuterTwo.name);
// 静态内部类中,不能直接访问外部类的私有实例变量
// System.out.println(age); //会报错
}
}
}
// 应用
public class Test4 {
public static void main(String[] args) {
//创建对象:外部类名.内部类名 对象名 = new 外部类名.内部类名();
OuterTwo.Inner inner = new OuterTwo.Inner();
inner.show();
}
}
3、局部内部类
4、匿名内部类
4.1 认识匿名内部类
4.2 匿名内部类的使用 (匿名内部类有简化代码的作用)
public class Test5 {
public static void main(String[] args) {
// 接口作为了类型,new了一个老师,匿名内部类
Swim s = new Swim() {
// 重写接口中的方法
@Override
public void swim() {
System.out.println("老师在自由泳,很快");
}
};
// 调用方法
start(s);
// 接口作为了类型,new了一个学生匿名内部类,
Swim s2 = new Swim() {
// 重写接口中的方法
@Override
public void swim() {
System.out.println("学生在蛙泳,很慢");
}
};
// 调用方法
start(s2);
}
//设计一个方法(不能放在main函数里面),作用是规划整个接口方法调用过程。参数可以接收老师,学生
public static void start(Swim s){
System.out.print("开始比赛。。");
s.swim();
System.out.println("比赛结束。。");
}
}
// 游泳接口,注意位置,不要放在Test5 类里面
interface Swim{
void swim();
}
4.3 匿名内部类在开发中的真实使用场景
不是主动去用匿名内部类,而是在开发中使用别人的功能的时候,别人可以让我们写一个匿名内部类
案例:数组排序
// 定义Student类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
// 姓名 年龄 身高 性别
private String name;
private int age;
private double height;
private char sex;
}
// 应用
import java.util.Arrays;
import java.util.Comparator;
public class Test6 {
public static void main(String[] args) {
Student[] students = new Student[4];
students[0] = new Student("小明", 18, 1.75, '男');
students[1] = new Student("小红", 24, 1.75, '女');
students[2] = new Student("小刚", 23, 1.75, '男');
students[3] = new Student("小花", 20, 1.75, '女');
// 需求:按年龄进行升序排序,直接调用java.util.Arrays中的sort方法
// sort里面的new Comparator<Student>(){}就是匿名类
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// 官方指定的**升序**排序规则
// 升序排序: 左边 > 右边 ,返回正整数
// 降序排序: 左边 < 右边 ,返回负整数
// 两边相等,返回0
// if (o1.getAge() > o2.getAge()) {
// return 1;
// } else if (o1.getAge() < o2.getAge()) {
// return -1;
// }
// return 0;
// 上面的代码简写为下面这一行
return o1.getAge() - o2.getAge(); // 升序
// return o1.getAge() - o2.getAge(); // 降序
}
});
// 打印排序后的数组,用for循环,使用索引的方式
for (int i = 0; i < students.length; i++) {
System.out.println(students[i]);
}
}
}
三、函数式编程
1、 Lambda表达式
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.getAge() - o1.getAge();
}
});
// Lambda表达式简化的写法
// Arrays.sort(students, (Student o1, Student o2) -> {
// return o2.getAge() - o1.getAge();
// });
//
1.1 Lambda简化写法
2、方法引用
2.1 静态方法引用
语法: 类名::静态方法
2.2 实例方法引用
// 实例方法
public int compareByHeight(Student 01, Student 02){
// 按身高进行比较
return Double.compare(01.getHeight(), 02.getHeight())
}
// 应用
Student t = new Student()
// Arrays.sort(student,(01,02) -> t.compareByHeight(01,02));
// 进一步简化写法: 实例方法引用 对象名::实例方法
Arrays.sort(student,t::compareByHeight);
2.3 特定类的方法引用
2.4 构造器引用
四、常用API
1、String
两种创建字符串方式的区别
2、String常用方法
3、案例
public class Test {
public static void main(String[] args) {
// 目标:生成随机验证码
String code = getCode(4);
System.out.println(code);
}
// 帮我生成指定位数的随机验证码返回,每位可能是大小写字母或者数字
// 帮我用String变量记住全部要用到的字符
public static String getCode(int n) {
// 1.定义一个String变量用来保存全部要用到的字符
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
// 2.循环n次,每次从str中随机抽取一个字符,拼接到code变量中
String code = "";
for (int i = 0; i < n; i++) {
// 获取随机索引
int index = (int)(Math.random() * str.length());
// 根据索引获取字符
code += str.charAt(index);
}
// 返回code
return code;
}
}
2、ArrayList
2.1 什么是集合?
2.2 集合的种类
2.3 ArrayList集合
public class ArrayListTest {
public static void main(String[] args) {
// 创建一个ArrayList对象
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("Hello");
list.add("World");
list.add("Java");
list.add("Programming");
System.out.println("ArrayList: " + list); // 输出:ArrayList: [Hello, World, Java, Programming]
// 遍历ArrayList对象
for (String str : list) {
System.out.println(str);
}
// 获取元素
String element = list.get(1);
System.out.println("Element at index 1: " + element);
// 删除数据
list.remove("Java"); //根据值删除
// list.remove(2); //根据索引删除
// 修改数据
list.set(1, "Python");
System.out.println("Updated ArrayList: " + list);
}
}
五、GUI:
5.1 什么是GUI?
1、GUI,全称GraphicalUserInterface,是指图形用户界面
2、通过图形元素(如窗口、按钮、文本框等)与用户进行交互。
3、与命令行界面(CLI)相比,GUI更加直观、友好。
5.2 Java的GUI编程包
import javax.swing.*;
public class TestGui {
public static void main(String[] args) {
// 创建一个窗口,有一个登录按钮
JFrame jf = new JFrame("登录界面");
// 创建一个面板
JPanel panel = new JPanel();
// 将面板添加到窗口
jf.add(panel);
// 设置窗口大小
jf.setSize(400, 300);
// 设置窗口居中
jf.setLocationRelativeTo(null);
// 设置窗口关闭
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 创建一个登录按钮
JButton loginButton = new JButton("登录");
// 将按钮添加到面板
panel.add(loginButton);
// 显示窗口
jf.setVisible(true);
}
}
5.3.1 FlowLayout
5.3.2 BorderLayout
5.3.3 GridLayout
5.3.4 BoxLayout
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
public class TestGui {
public static void main(String[] args) {
// 创建一个窗口,有一个登录按钮
JFrame jf = new JFrame("登录界面");
// 创建一个面板
JPanel panel = new JPanel();
// 将面板添加到窗口
jf.add(panel);
// 设置窗口大小
jf.setSize(400, 300);
// 设置窗口居中
jf.setLocationRelativeTo(null);
// 设置窗口关闭
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 创建一个登录按钮
JButton loginButton = new JButton("登录");
// 将按钮添加到面板
panel.add(loginButton);
// 添加点击事件
loginButton.addActionListener(e -> {
// 创建一个对话框
JOptionPane.showMessageDialog(jf, "登录成功!");
});
// 监听用户键盘上下左右四个按键事件
jf.addKeyListener(new KeyAdapter(){
// 重写方法,判断用户点了哪个键,并打印出来
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_UP:
System.out.println("向上");
break;
case KeyEvent.VK_DOWN:
System.out.println("向下");
break;
case KeyEvent.VK_LEFT:
System.out.println("向左");
break;
case KeyEvent.VK_RIGHT:
System.out.println("向右");
break;
}
}
});
// 显示窗口
jf.setVisible(true);
}
}