notes/Java语法完整指南.md
2025-06-25 19:21:02 +08:00

79 KiB
Raw Permalink Blame History

Java 语法完整指南

目录

  1. Java基础概念
  2. 数据类型
  3. 变量与常量
  4. 运算符
  5. 控制结构
  6. 数组
  7. 方法
  8. 面向对象编程
  9. 接口与抽象类
  10. 异常处理
  11. 集合框架
  12. 字符串处理
  13. 文件IO
  14. 多线程
  15. 泛型
  16. 注解
  17. Lambda表达式
  18. Stream API

Java基础概念

1.1 Java程序结构

// 包声明(可选)
package com.example.demo;

// 导入语句(可选)
import java.util.Scanner;
import java.util.*;

// 公共类定义
public class HelloWorld {
    // 主方法 - 程序入口点
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

1.2 编译与运行

# 编译Java源文件
javac HelloWorld.java

# 运行Java程序
java HelloWorld

1.3 Java特性

  • 面向对象:封装、继承、多态
  • 平台无关性:一次编写,到处运行
  • 自动内存管理:垃圾回收机制
  • 强类型检查:编译时类型检查
  • 多线程支持:内置多线程支持

数据类型

2.1 基本数据类型

// 整型
byte b = 127;        // 8位-128 到 127
short s = 32767;     // 16位-32,768 到 32,767
int i = 2147483647;  // 32位-2^31 到 2^31-1
long l = 9223372036854775807L; // 64位需要L后缀

// 浮点型
float f = 3.14f;     // 32位需要f后缀
double d = 3.14159;  // 64位默认浮点类型

// 字符型
char c = 'A';        // 16位Unicode字符
char unicode = '\u0041'; // Unicode表示法

// 布尔型
boolean flag = true; // true或false

2.2 引用数据类型

// 字符串
String str = "Hello Java";
String str2 = new String("Hello Java");

// 数组
int[] numbers = {1, 2, 3, 4, 5};
String[] names = new String[10];

// 对象
Scanner scanner = new Scanner(System.in);

2.3 类型转换

// 自动类型转换(小范围到大范围)
int i = 100;
long l = i;      // int自动转为long
double d = l;    // long自动转为double

// 强制类型转换
double d2 = 3.14;
int i2 = (int) d2;  // 结果为3小数部分丢失

// 字符串转换
String str = "123";
int num = Integer.parseInt(str);        // 字符串转int
double dbl = Double.parseDouble("3.14"); // 字符串转double
String s = String.valueOf(num);         // 数字转字符串

变量与常量

3.1 变量声明

// 变量声明语法:数据类型 变量名 = 初始值;
int age = 25;
String name = "张三";
boolean isStudent = true;

// 多变量声明
int a, b, c;
int x = 1, y = 2, z = 3;

// 变量作用域
public class VariableScope {
    static int globalVar = 100;  // 类变量
    int instanceVar = 200;       // 实例变量
    
    public void method() {
        int localVar = 300;      // 局部变量
        // localVar只在方法内有效
    }
}

3.2 常量定义

// 使用final关键字定义常量
final int MAX_SIZE = 100;
final double PI = 3.14159;
final String COMPANY_NAME = "科技有限公司";

// 类常量(静态常量)
public static final int DEFAULT_CAPACITY = 10;
public static final String VERSION = "1.0.0";

3.3 变量命名规范

// 良好的命名示例
int studentAge;          // 驼峰命名法
String firstName;        // 驼峰命名法
boolean isValid;         // 布尔值用is开头
final int MAX_COUNT = 50; // 常量用大写+下划线

// 避免的命名
int a, b, c;            // 无意义的名称
String s1, s2;          // 无意义的名称

运算符

4.1 算术运算符

int a = 10, b = 3;

int sum = a + b;        // 加法13
int diff = a - b;       // 减法7
int product = a * b;    // 乘法30
int quotient = a / b;   // 整除3
int remainder = a % b;  // 取余1

// 自增自减
int x = 5;
x++;    // 后自增x变为6
++x;    // 前自增x变为7
x--;    // 后自减x变为6
--x;    // 前自减x变为5

int y = 10;
int result1 = y++;  // result1 = 10, y = 11
int result2 = ++y;  // result2 = 12, y = 12

4.2 关系运算符

int a = 10, b = 5;

boolean eq = (a == b);   // 等于false
boolean ne = (a != b);   // 不等于true
boolean gt = (a > b);    // 大于true
boolean ge = (a >= b);   // 大于等于true
boolean lt = (a < b);    // 小于false
boolean le = (a <= b);   // 小于等于false

// 字符串比较
String str1 = "Hello";
String str2 = "Hello";
boolean same = str1.equals(str2);  // 内容比较true
boolean ref = (str1 == str2);      // 引用比较可能为false

4.3 逻辑运算符

boolean a = true, b = false;

boolean and = a && b;    // 逻辑与false
boolean or = a || b;     // 逻辑或true
boolean not = !a;        // 逻辑非false

// 短路运算
boolean result = (a || (10/0 > 0)); // 不会抛异常因为a为true

4.4 位运算符

int a = 60;  // 二进制111100
int b = 13;  // 二进制001101

int and = a & b;   // 按位与12 (001100)
int or = a | b;    // 按位或61 (111101)
int xor = a ^ b;   // 按位异或49 (110001)
int not = ~a;      // 按位取反:-61
int left = a << 2; // 左移240 (11110000)
int right = a >> 2;// 右移15 (1111)

4.5 赋值运算符

int x = 10;

x += 5;  // 等价于 x = x + 5结果15
x -= 3;  // 等价于 x = x - 3结果12
x *= 2;  // 等价于 x = x * 2结果24
x /= 4;  // 等价于 x = x / 4结果6
x %= 4;  // 等价于 x = x % 4结果2

4.6 三元运算符

int a = 10, b = 5;
int max = (a > b) ? a : b;  // 如果a>b则取a否则取b

String result = (score >= 60) ? "及格" : "不及格";

控制结构

5.1 条件语句

if语句

int score = 85;

// 单分支
if (score >= 60) {
    System.out.println("及格");
}

// 双分支
if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

// 多分支
if (score >= 90) {
    System.out.println("优秀");
} else if (score >= 80) {
    System.out.println("良好");
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

switch语句

int dayOfWeek = 3;

switch (dayOfWeek) {
    case 1:
        System.out.println("星期一");
        break;
    case 2:
        System.out.println("星期二");
        break;
    case 3:
        System.out.println("星期三");
        break;
    default:
        System.out.println("其他");
        break;
}

// Java 14+ 新语法
String result = switch (dayOfWeek) {
    case 1, 2, 3, 4, 5 -> "工作日";
    case 6, 7 -> "周末";
    default -> "无效";
};

5.2 循环语句

for循环

// 基本for循环
for (int i = 0; i < 10; i++) {
    System.out.println("第" + i + "次循环");
}

// 增强for循环for-each
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
    System.out.println(num);
}

// 嵌套循环
for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
        System.out.print(i + "," + j + " ");
    }
    System.out.println();
}

while循环

int i = 0;
while (i < 5) {
    System.out.println("i = " + i);
    i++;
}

// 无限循环
while (true) {
    // 某些条件下break
    if (condition) {
        break;
    }
}

do-while循环

int i = 0;
do {
    System.out.println("i = " + i);
    i++;
} while (i < 5);

5.3 跳转语句

// break跳出循环
for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break;  // 跳出循环
    }
    System.out.println(i);
}

// continue跳过本次循环
for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) {
        continue;  // 跳过偶数
    }
    System.out.println(i);
}

// 标签跳转
outer: for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if (i == 1 && j == 1) {
            break outer;  // 跳出外层循环
        }
        System.out.println(i + "," + j);
    }
}

数组

6.1 一维数组

// 数组声明和初始化
int[] numbers = new int[5];           // 声明长度为5的整型数组
int[] values = {1, 2, 3, 4, 5};      // 直接初始化
int[] scores = new int[]{90, 85, 92}; // 另一种初始化方式

// 数组访问
numbers[0] = 10;  // 设置第一个元素
int first = numbers[0];  // 获取第一个元素
int length = numbers.length;  // 获取数组长度

// 遍历数组
for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);
}

// 增强for循环遍历
for (int num : numbers) {
    System.out.println(num);
}

6.2 二维数组

// 二维数组声明和初始化
int[][] matrix = new int[3][4];  // 3行4列的矩阵
int[][] grid = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// 访问二维数组
matrix[0][0] = 1;  // 设置第一行第一列
int value = grid[1][2];  // 获取第二行第三列的值

// 遍历二维数组
for (int i = 0; i < grid.length; i++) {
    for (int j = 0; j < grid[i].length; j++) {
        System.out.print(grid[i][j] + " ");
    }
    System.out.println();
}

// 增强for循环遍历二维数组
for (int[] row : grid) {
    for (int value : row) {
        System.out.print(value + " ");
    }
    System.out.println();
}

6.3 数组常用操作

import java.util.Arrays;

int[] numbers = {5, 2, 8, 1, 9};

// 数组排序
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers)); // [1, 2, 5, 8, 9]

// 数组查找
int index = Arrays.binarySearch(numbers, 5); // 返回索引

// 数组填充
int[] filled = new int[5];
Arrays.fill(filled, 10); // 所有元素填充为10

// 数组复制
int[] copy1 = Arrays.copyOf(numbers, numbers.length);
int[] copy2 = numbers.clone();

// 数组比较
boolean equal = Arrays.equals(numbers, copy1);

方法

7.1 方法定义和调用

public class Calculator {
    // 基本方法定义
    public static int add(int a, int b) {
        return a + b;
    }
    
    // 无返回值方法
    public static void printMessage(String message) {
        System.out.println(message);
    }
    
    // 实例方法
    public int multiply(int a, int b) {
        return a * b;
    }
    
    public static void main(String[] args) {
        // 调用静态方法
        int sum = add(5, 3);
        printMessage("Hello");
        
        // 调用实例方法
        Calculator calc = new Calculator();
        int product = calc.multiply(4, 6);
    }
}

7.2 方法重载

public class MathUtils {
    // 方法重载:相同方法名,不同参数
    public static int add(int a, int b) {
        return a + b;
    }
    
    public static double add(double a, double b) {
        return a + b;
    }
    
    public static int add(int a, int b, int c) {
        return a + b + c;
    }
    
    public static String add(String a, String b) {
        return a + b;
    }
}

7.3 可变参数

public class VarArgs {
    // 可变参数方法
    public static int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        return total;
    }
    
    public static void main(String[] args) {
        System.out.println(sum(1, 2, 3));        // 6
        System.out.println(sum(1, 2, 3, 4, 5));  // 15
        System.out.println(sum());               // 0
    }
}

7.4 递归方法

public class Recursion {
    // 计算阶乘
    public static long factorial(int n) {
        if (n <= 1) {
            return 1;  // 基本情况
        } else {
            return n * factorial(n - 1);  // 递归调用
        }
    }
    
    // 计算斐波那契数列
    public static int fibonacci(int n) {
        if (n <= 1) {
            return n;
        } else {
            return fibonacci(n - 1) + fibonacci(n - 2);
        }
    }
}

面向对象编程

8.1 类和对象

// 类定义
public class Student {
    // 成员变量(属性)
    private String name;
    private int age;
    private String studentId;
    
    // 构造方法
    public Student() {
        // 无参构造方法
    }
    
    public Student(String name, int age, String studentId) {
        this.name = name;
        this.age = age;
        this.studentId = studentId;
    }
    
    // getter和setter方法
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        if (age >= 0 && age <= 150) {
            this.age = age;
        }
    }
    
    // 成员方法
    public void study(String subject) {
        System.out.println(name + "正在学习" + subject);
    }
    
    public void displayInfo() {
        System.out.println("姓名:" + name + ",年龄:" + age + ",学号:" + studentId);
    }
    
    // toString方法重写
    @Override
    public String toString() {
        return "Student{name='" + name + "', age=" + age + ", studentId='" + studentId + "'}";
    }
}

// 使用类创建对象
public class TestStudent {
    public static void main(String[] args) {
        // 创建对象
        Student student1 = new Student();
        student1.setName("张三");
        student1.setAge(20);
        
        Student student2 = new Student("李四", 19, "2023001");
        
        // 调用方法
        student1.study("Java");
        student2.displayInfo();
    }
}

8.2 封装

public class BankAccount {
    // 私有成员变量,外部无法直接访问
    private String accountNumber;
    private double balance;
    private String ownerName;
    
    public BankAccount(String accountNumber, String ownerName, double initialBalance) {
        this.accountNumber = accountNumber;
        this.ownerName = ownerName;
        this.balance = initialBalance >= 0 ? initialBalance : 0;
    }
    
    // 提供公共方法来访问和操作私有数据
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("存款成功,当前余额:" + balance);
        } else {
            System.out.println("存款金额必须大于0");
        }
    }
    
    public boolean withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("取款成功,当前余额:" + balance);
            return true;
        } else {
            System.out.println("取款失败:余额不足或金额无效");
            return false;
        }
    }
    
    // 只读属性
    public double getBalance() {
        return balance;
    }
    
    public String getAccountNumber() {
        return accountNumber;
    }
    
    public String getOwnerName() {
        return ownerName;
    }
}

8.3 继承

// 父类(基类)
public class Animal {
    protected String name;
    protected int age;
    
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void eat() {
        System.out.println(name + "正在吃东西");
    }
    
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
    
    public void makeSound() {
        System.out.println(name + "发出声音");
    }
}

// 子类(派生类)
public class Dog extends Animal {
    private String breed;
    
    public Dog(String name, int age, String breed) {
        super(name, age);  // 调用父类构造方法
        this.breed = breed;
    }
    
    // 重写父类方法
    @Override
    public void makeSound() {
        System.out.println(name + "汪汪叫");
    }
    
    // 子类特有方法
    public void wagTail() {
        System.out.println(name + "正在摇尾巴");
    }
    
    public void fetch() {
        System.out.println(name + "正在捡球");
    }
}

public class Cat extends Animal {
    public Cat(String name, int age) {
        super(name, age);
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + "喵喵叫");
    }
    
    public void climb() {
        System.out.println(name + "正在爬树");
    }
}

8.4 多态

public class PolymorphismDemo {
    public static void main(String[] args) {
        // 多态:父类引用指向子类对象
        Animal[] animals = {
            new Dog("旺财", 3, "金毛"),
            new Cat("咪咪", 2),
            new Dog("大黄", 5, "土狗")
        };
        
        // 多态调用:同一个方法调用,不同的实现
        for (Animal animal : animals) {
            animal.eat();        // 调用父类方法
            animal.makeSound();  // 调用各自重写的方法
            System.out.println("---");
        }
        
        // 类型检查和转换
        for (Animal animal : animals) {
            if (animal instanceof Dog) {
                Dog dog = (Dog) animal;  // 向下转型
                dog.wagTail();           // 调用子类特有方法
            } else if (animal instanceof Cat) {
                Cat cat = (Cat) animal;
                cat.climb();
            }
        }
    }
}

接口与抽象类

9.1 接口

// 接口定义
public interface Drawable {
    // 接口中的变量默认是public static final
    double PI = 3.14159;
    
    // 抽象方法默认public abstract
    void draw();
    void resize(double scale);
    
    // Java 8+:默认方法
    default void display() {
        System.out.println("显示图形");
    }
    
    // Java 8+:静态方法
    static void printInfo() {
        System.out.println("这是一个可绘制接口");
    }
}

// 接口实现
public class Circle implements Drawable {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制半径为" + radius + "的圆形");
    }
    
    @Override
    public void resize(double scale) {
        radius *= scale;
        System.out.println("圆形缩放后半径为:" + radius);
    }
}

// 多接口实现
public interface Movable {
    void move(int x, int y);
}

public class Rectangle implements Drawable, Movable {
    private double width, height;
    private int x, y;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制矩形:宽=" + width + ",高=" + height);
    }
    
    @Override
    public void resize(double scale) {
        width *= scale;
        height *= scale;
    }
    
    @Override
    public void move(int x, int y) {
        this.x = x;
        this.y = y;
        System.out.println("矩形移动到:(" + x + ", " + y + ")");
    }
}

9.2 抽象类

// 抽象类定义
public abstract class Shape {
    protected String color;
    protected double x, y;
    
    public Shape(String color, double x, double y) {
        this.color = color;
        this.x = x;
        this.y = y;
    }
    
    // 抽象方法:子类必须实现
    public abstract double getArea();
    public abstract double getPerimeter();
    
    // 具体方法:子类可以直接使用
    public void setPosition(double x, double y) {
        this.x = x;
        this.y = y;
    }
    
    public void setColor(String color) {
        this.color = color;
    }
    
    public void displayInfo() {
        System.out.println("颜色:" + color + ",位置:(" + x + ", " + y + ")");
        System.out.println("面积:" + getArea() + ",周长:" + getPerimeter());
    }
}

// 抽象类的实现
public class Triangle extends Shape {
    private double side1, side2, side3;
    
    public Triangle(String color, double x, double y, double side1, double side2, double side3) {
        super(color, x, y);
        this.side1 = side1;
        this.side2 = side2;
        this.side3 = side3;
    }
    
    @Override
    public double getArea() {
        // 海伦公式计算三角形面积
        double s = (side1 + side2 + side3) / 2;
        return Math.sqrt(s * (s - side1) * (s - side2) * (s - side3));
    }
    
    @Override
    public double getPerimeter() {
        return side1 + side2 + side3;
    }
}

异常处理

10.1 异常类型

// Java异常层次结构
/*
Throwable
├── Error错误
│   ├── OutOfMemoryError
│   ├── StackOverflowError
│   └── ...
└── Exception异常
    ├── RuntimeException运行时异常非检查异常
    │   ├── NullPointerException
    │   ├── ArrayIndexOutOfBoundsException
    │   ├── IllegalArgumentException
    │   └── ...
    └── 检查异常
        ├── IOException
        ├── ClassNotFoundException
        └── ...
*/

10.2 异常处理语法

public class ExceptionHandling {
    public static void main(String[] args) {
        // try-catch基本语法
        try {
            int result = 10 / 0;  // 可能抛出异常的代码
        } catch (ArithmeticException e) {
            System.out.println("算术异常:" + e.getMessage());
        }
        
        // 多个catch块
        try {
            int[] arr = new int[5];
            arr[10] = 100;  // 数组越界
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界:" + e.getMessage());
        } catch (Exception e) {
            System.out.println("其他异常:" + e.getMessage());
        }
        
        // try-catch-finally
        try {
            // 可能出现异常的代码
            performOperation();
        } catch (Exception e) {
            System.out.println("捕获异常:" + e.getMessage());
        } finally {
            // 无论是否出现异常都会执行
            System.out.println("清理资源");
        }
        
        // try-with-resourcesJava 7+
        try (Scanner scanner = new Scanner(System.in)) {
            String input = scanner.nextLine();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // scanner会自动关闭
    }
    
    public static void performOperation() throws Exception {
        // 可能抛出异常的方法
        throw new Exception("操作失败");
    }
}

10.3 自定义异常

// 自定义异常类
public class InsufficientBalanceException extends Exception {
    private double balance;
    private double amount;
    
    public InsufficientBalanceException(double balance, double amount) {
        super("余额不足:当前余额" + balance + ",尝试取款" + amount);
        this.balance = balance;
        this.amount = amount;
    }
    
    public double getBalance() {
        return balance;
    }
    
    public double getAmount() {
        return amount;
    }
}

// 使用自定义异常
public class BankAccountWithException {
    private double balance;
    
    public BankAccountWithException(double initialBalance) {
        this.balance = initialBalance;
    }
    
    public void withdraw(double amount) throws InsufficientBalanceException {
        if (amount > balance) {
            throw new InsufficientBalanceException(balance, amount);
        }
        balance -= amount;
        System.out.println("取款成功,余额:" + balance);
    }
    
    public static void main(String[] args) {
        BankAccountWithException account = new BankAccountWithException(1000);
        
        try {
            account.withdraw(1500);  // 会抛出异常
        } catch (InsufficientBalanceException e) {
            System.out.println("取款失败:" + e.getMessage());
            System.out.println("当前余额:" + e.getBalance());
        }
    }
}

10.4 异常传播和处理最佳实践

public class ExceptionBestPractices {
    // 方法声明抛出异常
    public void readFile(String filename) throws IOException {
        FileReader file = new FileReader(filename);
        // 文件操作...
        file.close();
    }
    
    // 异常链
    public void processData() throws DataProcessingException {
        try {
            // 一些可能出错的操作
            riskyOperation();
        } catch (SQLException e) {
            // 包装异常,保留原始异常信息
            throw new DataProcessingException("数据处理失败", e);
        }
    }
    
    // 资源管理的最佳实践
    public String readFileContent(String filename) {
        StringBuilder content = new StringBuilder();
        
        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line).append("\n");
            }
        } catch (IOException e) {
            System.err.println("读取文件失败:" + e.getMessage());
            e.printStackTrace();
        }
        
        return content.toString();
    }
}

集合框架

11.1 List接口

import java.util.*;

public class ListDemo {
    public static void main(String[] args) {
        // ArrayList动态数组
        List<String> arrayList = new ArrayList<>();
        arrayList.add("apple");
        arrayList.add("banana");
        arrayList.add("orange");
        arrayList.add(1, "grape");  // 在指定位置插入
        
        // LinkedList双向链表
        List<String> linkedList = new LinkedList<>();
        linkedList.add("first");
        linkedList.add("second");
        ((LinkedList<String>) linkedList).addFirst("zero");  // 在开头添加
        ((LinkedList<String>) linkedList).addLast("last");   // 在末尾添加
        
        // Vector线程安全的动态数组
        List<Integer> vector = new Vector<>();
        vector.add(1);
        vector.add(2);
        vector.add(3);
        
        // 遍历List
        for (String item : arrayList) {
            System.out.println(item);
        }
        
        // 使用迭代器
        Iterator<String> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        
        // 常用操作
        System.out.println("大小:" + arrayList.size());
        System.out.println("包含apple" + arrayList.contains("apple"));
        System.out.println("apple的索引" + arrayList.indexOf("apple"));
        arrayList.remove("banana");  // 删除元素
        arrayList.remove(0);         // 删除指定位置元素
    }
}

11.2 Set接口

import java.util.*;

public class SetDemo {
    public static void main(String[] args) {
        // HashSet基于哈希表无序不允许重复
        Set<String> hashSet = new HashSet<>();
        hashSet.add("java");
        hashSet.add("python");
        hashSet.add("javascript");
        hashSet.add("java");  // 重复元素不会被添加
        
        System.out.println("HashSet: " + hashSet);
        
        // LinkedHashSet保持插入顺序的HashSet
        Set<String> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("first");
        linkedHashSet.add("second");
        linkedHashSet.add("third");
        
        System.out.println("LinkedHashSet: " + linkedHashSet);
        
        // TreeSet基于红黑树自动排序
        Set<Integer> treeSet = new TreeSet<>();
        treeSet.add(5);
        treeSet.add(2);
        treeSet.add(8);
        treeSet.add(1);
        
        System.out.println("TreeSet: " + treeSet);  // 自动排序输出
        
        // 集合操作
        Set<String> set1 = new HashSet<>(Arrays.asList("a", "b", "c"));
        Set<String> set2 = new HashSet<>(Arrays.asList("b", "c", "d"));
        
        // 并集
        Set<String> union = new HashSet<>(set1);
        union.addAll(set2);
        System.out.println("并集: " + union);
        
        // 交集
        Set<String> intersection = new HashSet<>(set1);
        intersection.retainAll(set2);
        System.out.println("交集: " + intersection);
        
        // 差集
        Set<String> difference = new HashSet<>(set1);
        difference.removeAll(set2);
        System.out.println("差集: " + difference);
    }
}

11.3 Map接口

import java.util.*;

public class MapDemo {
    public static void main(String[] args) {
        // HashMap基于哈希表无序
        Map<String, Integer> hashMap = new HashMap<>();
        hashMap.put("apple", 5);
        hashMap.put("banana", 3);
        hashMap.put("orange", 8);
        
        // LinkedHashMap保持插入顺序
        Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("first", 1);
        linkedHashMap.put("second", 2);
        linkedHashMap.put("third", 3);
        
        // TreeMap基于红黑树按键自动排序
        Map<String, Integer> treeMap = new TreeMap<>();
        treeMap.put("zebra", 1);
        treeMap.put("apple", 2);
        treeMap.put("banana", 3);
        
        System.out.println("TreeMap (自动排序): " + treeMap);
        
        // Map操作
        System.out.println("apple的值: " + hashMap.get("apple"));
        System.out.println("包含键apple: " + hashMap.containsKey("apple"));
        System.out.println("包含值5: " + hashMap.containsValue(5));
        
        // 遍历Map
        // 方法1遍历键
        for (String key : hashMap.keySet()) {
            System.out.println(key + " = " + hashMap.get(key));
        }
        
        // 方法2遍历键值对
        for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
        
        // 方法3Java 8 forEach
        hashMap.forEach((key, value) -> System.out.println(key + " = " + value));
        
        // Map的其他操作
        hashMap.putIfAbsent("grape", 6);  // 键不存在时才添加
        hashMap.replace("apple", 10);     // 替换值
        hashMap.remove("banana");         // 删除键值对
    }
}

11.4 Collections工具类

import java.util.*;

public class CollectionsDemo {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 2, 8, 1, 9, 3));
        
        // 排序
        Collections.sort(numbers);
        System.out.println("升序排序: " + numbers);
        
        Collections.sort(numbers, Collections.reverseOrder());
        System.out.println("降序排序: " + numbers);
        
        // 自定义比较器排序
        List<String> words = Arrays.asList("apple", "pie", "a", "application");
        Collections.sort(words, Comparator.comparing(String::length));
        System.out.println("按长度排序: " + words);
        
        // 查找
        Collections.sort(numbers);  // 二分查找需要有序数组
        int index = Collections.binarySearch(numbers, 5);
        System.out.println("5的位置: " + index);
        
        // 其他操作
        Collections.shuffle(numbers);        // 随机打乱
        Collections.reverse(numbers);        // 反转
        Collections.fill(numbers, 0);        // 填充
        System.out.println("最大值: " + Collections.max(numbers));
        System.out.println("最小值: " + Collections.min(numbers));
        
        // 创建不可变集合
        List<String> immutableList = Collections.unmodifiableList(
            Arrays.asList("a", "b", "c"));
        
        // 线程安全集合
        List<String> syncList = Collections.synchronizedList(new ArrayList<>());
        Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());
    }
}

字符串处理

12.1 String类

public class StringDemo {
    public static void main(String[] args) {
        // 字符串创建
        String str1 = "Hello";          // 字符串字面量
        String str2 = new String("Hello"); // 使用构造方法
        String str3 = "World";
        
        // 字符串连接
        String result1 = str1 + " " + str3;
        String result2 = str1.concat(" ").concat(str3);
        
        // 字符串长度
        System.out.println("长度: " + str1.length());
        
        // 字符串比较
        System.out.println("相等: " + str1.equals("Hello"));
        System.out.println("忽略大小写相等: " + str1.equalsIgnoreCase("hello"));
        System.out.println("比较: " + str1.compareTo("Help"));  // 返回int
        
        // 字符串查找
        String text = "Hello Java World";
        System.out.println("包含Java: " + text.contains("Java"));
        System.out.println("以Hello开头: " + text.startsWith("Hello"));
        System.out.println("以World结尾: " + text.endsWith("World"));
        System.out.println("Java的位置: " + text.indexOf("Java"));
        System.out.println("最后一个o的位置: " + text.lastIndexOf("o"));
        
        // 字符串截取
        System.out.println("子字符串: " + text.substring(6));      // 从位置6开始
        System.out.println("子字符串: " + text.substring(6, 10));  // 从6到10不包含10
        
        // 字符串替换
        System.out.println("替换: " + text.replace("Java", "Python"));
        System.out.println("替换第一个: " + text.replaceFirst("o", "0"));
        System.out.println("正则替换: " + text.replaceAll("\\s+", "_"));
        
        // 字符串分割
        String csv = "apple,banana,orange,grape";
        String[] fruits = csv.split(",");
        for (String fruit : fruits) {
            System.out.println(fruit);
        }
        
        // 大小写转换
        System.out.println("大写: " + text.toUpperCase());
        System.out.println("小写: " + text.toLowerCase());
        
        // 去除空白
        String spaced = "  Hello World  ";
        System.out.println("去除前后空白: '" + spaced.trim() + "'");
        
        // 字符串格式化
        String formatted = String.format("姓名: %s, 年龄: %d, 分数: %.2f", 
                                       "张三", 25, 89.567);
        System.out.println(formatted);
    }
}

12.2 StringBuilder和StringBuffer

public class StringBuilderDemo {
    public static void main(String[] args) {
        // StringBuilder非线程安全性能更好
        StringBuilder sb = new StringBuilder();
        sb.append("Hello");
        sb.append(" ");
        sb.append("World");
        sb.insert(5, " Java");        // 在位置5插入
        sb.delete(5, 10);             // 删除位置5到10的字符
        sb.reverse();                 // 反转字符串
        
        System.out.println("StringBuilder结果: " + sb.toString());
        
        // StringBuffer线程安全
        StringBuffer sbf = new StringBuffer("Hello");
        sbf.append(" World");
        System.out.println("StringBuffer结果: " + sbf.toString());
        
        // 性能比较示例
        long startTime, endTime;
        
        // String连接效率低
        startTime = System.currentTimeMillis();
        String str = "";
        for (int i = 0; i < 10000; i++) {
            str += "a";
        }
        endTime = System.currentTimeMillis();
        System.out.println("String连接耗时: " + (endTime - startTime) + "ms");
        
        // StringBuilder连接效率高
        startTime = System.currentTimeMillis();
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 10000; i++) {
            builder.append("a");
        }
        String result = builder.toString();
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder连接耗时: " + (endTime - startTime) + "ms");
    }
}

12.3 正则表达式

import java.util.regex.*;

public class RegexDemo {
    public static void main(String[] args) {
        String text = "联系电话138-0013-8000邮箱user@example.com";
        
        // 匹配手机号
        String phonePattern = "\\d{3}-\\d{4}-\\d{4}";
        Pattern phoneRegex = Pattern.compile(phonePattern);
        Matcher phoneMatcher = phoneRegex.matcher(text);
        
        if (phoneMatcher.find()) {
            System.out.println("找到手机号: " + phoneMatcher.group());
        }
        
        // 匹配邮箱
        String emailPattern = "[\\w._%+-]+@[\\w.-]+\\.[A-Za-z]{2,}";
        Pattern emailRegex = Pattern.compile(emailPattern);
        Matcher emailMatcher = emailRegex.matcher(text);
        
        if (emailMatcher.find()) {
            System.out.println("找到邮箱: " + emailMatcher.group());
        }
        
        // 使用String类的正则方法
        String input = "abc123def456ghi";
        
        // 检查是否匹配
        System.out.println("包含数字: " + input.matches(".*\\d+.*"));
        
        // 分割
        String[] parts = input.split("\\d+");
        System.out.println("分割结果: " + Arrays.toString(parts));
        
        // 替换
        String replaced = input.replaceAll("\\d+", "#");
        System.out.println("替换数字: " + replaced);
        
        // 常用正则表达式
        validateInputs();
    }
    
    public static void validateInputs() {
        String[] testData = {
            "user@example.com",     // 邮箱
            "13800138000",          // 手机号
            "abc123",               // 用户名
            "P@ssw0rd123"           // 密码
        };
        
        // 邮箱验证
        String emailRegex = "^[\\w._%+-]+@[\\w.-]+\\.[A-Za-z]{2,}$";
        
        // 手机号验证(中国大陆)
        String phoneRegex = "^1[3-9]\\d{9}$";
        
        // 用户名验证字母开头包含字母数字下划线3-16位
        String usernameRegex = "^[a-zA-Z][a-zA-Z0-9_]{2,15}$";
        
        // 密码验证至少8位包含大小写字母、数字、特殊字符
        String passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$";
        
        System.out.println("邮箱验证: " + testData[0].matches(emailRegex));
        System.out.println("手机号验证: " + testData[1].matches(phoneRegex));
        System.out.println("用户名验证: " + testData[2].matches(usernameRegex));
        System.out.println("密码验证: " + testData[3].matches(passwordRegex));
    }
}

文件IO

13.1 文件操作基础

import java.io.*;
import java.nio.file.*;
import java.util.List;

public class FileIODemo {
    public static void main(String[] args) {
        // File类基本操作
        File file = new File("test.txt");
        File directory = new File("testDir");
        
        try {
            // 文件操作
            if (!file.exists()) {
                file.createNewFile();
                System.out.println("文件创建成功");
            }
            
            System.out.println("文件名: " + file.getName());
            System.out.println("绝对路径: " + file.getAbsolutePath());
            System.out.println("文件大小: " + file.length() + " 字节");
            System.out.println("是否为文件: " + file.isFile());
            System.out.println("是否为目录: " + file.isDirectory());
            System.out.println("可读: " + file.canRead());
            System.out.println("可写: " + file.canWrite());
            System.out.println("最后修改时间: " + new Date(file.lastModified()));
            
            // 目录操作
            if (!directory.exists()) {
                directory.mkdir();  // 创建单级目录
                // directory.mkdirs();  // 创建多级目录
                System.out.println("目录创建成功");
            }
            
            // 列出目录内容
            File currentDir = new File(".");
            String[] files = currentDir.list();
            if (files != null) {
                System.out.println("当前目录文件:");
                for (String fileName : files) {
                    System.out.println("  " + fileName);
                }
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

13.2 字符流操作

import java.io.*;

public class CharacterStreamDemo {
    public static void main(String[] args) {
        writeTextFile();
        readTextFile();
        copyTextFile();
    }
    
    // 写入文本文件
    public static void writeTextFile() {
        try (FileWriter writer = new FileWriter("output.txt");
             BufferedWriter bufferedWriter = new BufferedWriter(writer)) {
            
            bufferedWriter.write("第一行文本\n");
            bufferedWriter.write("第二行文本\n");
            bufferedWriter.write("第三行文本\n");
            bufferedWriter.flush();  // 强制写入
            
            System.out.println("文件写入完成");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 读取文本文件
    public static void readTextFile() {
        try (FileReader reader = new FileReader("output.txt");
             BufferedReader bufferedReader = new BufferedReader(reader)) {
            
            String line;
            int lineNumber = 1;
            
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println("行" + lineNumber + ": " + line);
                lineNumber++;
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 复制文本文件
    public static void copyTextFile() {
        try (FileReader reader = new FileReader("output.txt");
             FileWriter writer = new FileWriter("copy.txt");
             BufferedReader bufferedReader = new BufferedReader(reader);
             BufferedWriter bufferedWriter = new BufferedWriter(writer)) {
            
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                bufferedWriter.write(line);
                bufferedWriter.newLine();
            }
            
            System.out.println("文件复制完成");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

13.3 字节流操作

import java.io.*;

public class ByteStreamDemo {
    public static void main(String[] args) {
        writeBinaryFile();
        readBinaryFile();
        copyBinaryFile();
    }
    
    // 写入二进制文件
    public static void writeBinaryFile() {
        try (FileOutputStream fos = new FileOutputStream("data.bin");
             BufferedOutputStream bos = new BufferedOutputStream(fos);
             DataOutputStream dos = new DataOutputStream(bos)) {
            
            // 写入不同类型的数据
            dos.writeInt(42);
            dos.writeDouble(3.14159);
            dos.writeUTF("Hello Binary");
            dos.writeBoolean(true);
            
            System.out.println("二进制文件写入完成");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 读取二进制文件
    public static void readBinaryFile() {
        try (FileInputStream fis = new FileInputStream("data.bin");
             BufferedInputStream bis = new BufferedInputStream(fis);
             DataInputStream dis = new DataInputStream(bis)) {
            
            // 按写入顺序读取数据
            int intValue = dis.readInt();
            double doubleValue = dis.readDouble();
            String stringValue = dis.readUTF();
            boolean booleanValue = dis.readBoolean();
            
            System.out.println("读取的数据:");
            System.out.println("int: " + intValue);
            System.out.println("double: " + doubleValue);
            System.out.println("String: " + stringValue);
            System.out.println("boolean: " + booleanValue);
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 复制二进制文件
    public static void copyBinaryFile() {
        try (FileInputStream fis = new FileInputStream("data.bin");
             FileOutputStream fos = new FileOutputStream("data_copy.bin");
             BufferedInputStream bis = new BufferedInputStream(fis);
             BufferedOutputStream bos = new BufferedOutputStream(fos)) {
            
            byte[] buffer = new byte[1024];
            int bytesRead;
            
            while ((bytesRead = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
            }
            
            System.out.println("二进制文件复制完成");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

13.4 NIO文件操作

import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.io.IOException;
import java.util.List;

public class NIOFileDemo {
    public static void main(String[] args) {
        try {
            // 使用Path操作文件
            Path filePath = Paths.get("nio_test.txt");
            Path dirPath = Paths.get("nio_dir");
            
            // 写入文件
            String content = "第一行\n第二行\n第三行";
            Files.write(filePath, content.getBytes(StandardCharsets.UTF_8));
            System.out.println("文件写入完成");
            
            // 读取文件
            List<String> lines = Files.readAllLines(filePath, StandardCharsets.UTF_8);
            System.out.println("文件内容:");
            for (String line : lines) {
                System.out.println("  " + line);
            }
            
            // 文件信息
            System.out.println("文件大小: " + Files.size(filePath) + " 字节");
            System.out.println("文件存在: " + Files.exists(filePath));
            System.out.println("是否为目录: " + Files.isDirectory(filePath));
            
            // 创建目录
            if (!Files.exists(dirPath)) {
                Files.createDirectory(dirPath);
                System.out.println("目录创建完成");
            }
            
            // 复制文件
            Path copyPath = dirPath.resolve("copy.txt");
            Files.copy(filePath, copyPath, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("文件复制完成");
            
            // 移动文件
            Path movePath = dirPath.resolve("moved.txt");
            Files.move(copyPath, movePath, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("文件移动完成");
            
            // 删除文件
            Files.deleteIfExists(movePath);
            System.out.println("文件删除完成");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

多线程

14.1 创建线程

// 方法1继承Thread类
class MyThread extends Thread {
    private String threadName;
    
    public MyThread(String name) {
        this.threadName = name;
    }
    
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(threadName + " - 计数: " + i);
            try {
                Thread.sleep(1000);  // 暂停1秒
            } catch (InterruptedException e) {
                System.out.println(threadName + " 被中断");
                return;
            }
        }
        System.out.println(threadName + " 执行完成");
    }
}

// 方法2实现Runnable接口
class MyRunnable implements Runnable {
    private String taskName;
    
    public MyRunnable(String name) {
        this.taskName = name;
    }
    
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(taskName + " - 执行: " + i);
            try {
                Thread.sleep(800);
            } catch (InterruptedException e) {
                System.out.println(taskName + " 被中断");
                return;
            }
        }
        System.out.println(taskName + " 任务完成");
    }
}

public class ThreadDemo {
    public static void main(String[] args) {
        // 使用Thread类
        MyThread thread1 = new MyThread("线程1");
        MyThread thread2 = new MyThread("线程2");
        
        thread1.start();  // 启动线程
        thread2.start();
        
        // 使用Runnable接口
        Thread thread3 = new Thread(new MyRunnable("任务A"));
        Thread thread4 = new Thread(new MyRunnable("任务B"));
        
        thread3.start();
        thread4.start();
        
        // 使用匿名类
        Thread thread5 = new Thread(() -> {
            for (int i = 1; i <= 3; i++) {
                System.out.println("Lambda线程 - " + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    break;
                }
            }
        });
        thread5.start();
        
        // 等待所有线程完成
        try {
            thread1.join();
            thread2.join();
            thread3.join();
            thread4.join();
            thread5.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("所有线程执行完成");
    }
}

14.2 线程同步

// 同步问题示例
class Counter {
    private int count = 0;
    
    // 非同步方法(可能出现并发问题)
    public void incrementUnsafe() {
        count++;
    }
    
    // 同步方法
    public synchronized void increment() {
        count++;
    }
    
    // 同步代码块
    public void incrementWithBlock() {
        synchronized (this) {
            count++;
        }
    }
    
    public synchronized int getCount() {
        return count;
    }
}

public class SynchronizationDemo {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        
        // 创建多个线程同时操作计数器
        Thread[] threads = new Thread[10];
        
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    counter.increment();  // 使用同步方法
                }
            });
            threads[i].start();
        }
        
        // 等待所有线程完成
        for (Thread thread : threads) {
            thread.join();
        }
        
        System.out.println("最终计数: " + counter.getCount());
        // 期望结果10000
    }
}

14.3 线程通信

// 生产者-消费者模式
class SharedBuffer {
    private int[] buffer;
    private int count = 0;
    private int in = 0;
    private int out = 0;
    
    public SharedBuffer(int size) {
        buffer = new int[size];
    }
    
    // 生产者方法
    public synchronized void produce(int item) throws InterruptedException {
        while (count == buffer.length) {
            wait();  // 缓冲区满,等待
        }
        
        buffer[in] = item;
        in = (in + 1) % buffer.length;
        count++;
        
        System.out.println("生产: " + item + ",缓冲区数量: " + count);
        notifyAll();  // 通知消费者
    }
    
    // 消费者方法
    public synchronized int consume() throws InterruptedException {
        while (count == 0) {
            wait();  // 缓冲区空,等待
        }
        
        int item = buffer[out];
        out = (out + 1) % buffer.length;
        count--;
        
        System.out.println("消费: " + item + ",缓冲区数量: " + count);
        notifyAll();  // 通知生产者
        
        return item;
    }
}

class Producer extends Thread {
    private SharedBuffer buffer;
    
    public Producer(SharedBuffer buffer) {
        this.buffer = buffer;
    }
    
    @Override
    public void run() {
        try {
            for (int i = 1; i <= 10; i++) {
                buffer.produce(i);
                Thread.sleep(100);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

class Consumer extends Thread {
    private SharedBuffer buffer;
    
    public Consumer(SharedBuffer buffer) {
        this.buffer = buffer;
    }
    
    @Override
    public void run() {
        try {
            for (int i = 1; i <= 10; i++) {
                buffer.consume();
                Thread.sleep(150);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public class ProducerConsumerDemo {
    public static void main(String[] args) throws InterruptedException {
        SharedBuffer buffer = new SharedBuffer(5);
        
        Producer producer = new Producer(buffer);
        Consumer consumer = new Consumer(buffer);
        
        producer.start();
        consumer.start();
        
        producer.join();
        consumer.join();
        
        System.out.println("生产者-消费者演示完成");
    }
}

14.4 线程池

import java.util.concurrent.*;

public class ThreadPoolDemo {
    public static void main(String[] args) {
        // 固定大小线程池
        ExecutorService fixedPool = Executors.newFixedThreadPool(3);
        
        // 提交任务
        for (int i = 1; i <= 10; i++) {
            final int taskId = i;
            fixedPool.submit(() -> {
                System.out.println("任务" + taskId + " 由线程 " + 
                                 Thread.currentThread().getName() + " 执行");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
        
        // 关闭线程池
        fixedPool.shutdown();
        
        // 缓存线程池
        ExecutorService cachedPool = Executors.newCachedThreadPool();
        
        // 单线程线程池
        ExecutorService singlePool = Executors.newSingleThreadExecutor();
        
        // 定时任务线程池
        ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(2);
        
        // 延迟执行
        scheduledPool.schedule(() -> {
            System.out.println("延迟任务执行");
        }, 2, TimeUnit.SECONDS);
        
        // 定期执行
        scheduledPool.scheduleAtFixedRate(() -> {
            System.out.println("定期任务: " + System.currentTimeMillis());
        }, 1, 3, TimeUnit.SECONDS);
        
        // 使用Future获取结果
        Future<Integer> future = fixedPool.submit(() -> {
            Thread.sleep(2000);
            return 42;
        });
        
        try {
            Integer result = future.get(3, TimeUnit.SECONDS);
            System.out.println("任务结果: " + result);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            e.printStackTrace();
        }
        
        // 关闭所有线程池
        try {
            if (!fixedPool.awaitTermination(60, TimeUnit.SECONDS)) {
                fixedPool.shutdownNow();
            }
        } catch (InterruptedException e) {
            fixedPool.shutdownNow();
        }
        
        scheduledPool.shutdown();
    }
}

泛型

15.1 泛型基础

// 泛型类
public class GenericBox<T> {
    private T content;
    
    public GenericBox(T content) {
        this.content = content;
    }
    
    public T getContent() {
        return content;
    }
    
    public void setContent(T content) {
        this.content = content;
    }
    
    @Override
    public String toString() {
        return "Box[" + content + "]";
    }
}

// 泛型接口
public interface GenericComparable<T> {
    int compare(T other);
}

// 实现泛型接口
public class Person implements GenericComparable<Person> {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public int compare(Person other) {
        return Integer.compare(this.age, other.age);
    }
    
    // getters和toString...
}

public class GenericDemo {
    public static void main(String[] args) {
        // 使用泛型类
        GenericBox<String> stringBox = new GenericBox<>("Hello");
        System.out.println(stringBox.getContent());
        
        GenericBox<Integer> intBox = new GenericBox<>(42);
        System.out.println(intBox.getContent());
        
        // 钻石操作符Java 7+
        GenericBox<Double> doubleBox = new GenericBox<>(3.14);
        
        // 泛型方法调用
        String[] strings = {"apple", "banana", "cherry"};
        String maxString = findMax(strings);
        System.out.println("最大字符串: " + maxString);
        
        Integer[] numbers = {5, 2, 8, 1, 9};
        Integer maxNumber = findMax(numbers);
        System.out.println("最大数字: " + maxNumber);
    }
    
    // 泛型方法
    public static <T extends Comparable<T>> T findMax(T[] array) {
        if (array == null || array.length == 0) {
            return null;
        }
        
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i].compareTo(max) > 0) {
                max = array[i];
            }
        }
        return max;
    }
}

15.2 泛型通配符

import java.util.*;

public class WildcardDemo {
    public static void main(String[] args) {
        List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5);
        List<Double> doubleList = Arrays.asList(1.1, 2.2, 3.3);
        List<String> stringList = Arrays.asList("a", "b", "c");
        
        // 上界通配符
        printNumbers(intList);
        printNumbers(doubleList);
        // printNumbers(stringList);  // 编译错误String不是Number的子类
        
        // 下界通配符
        List<Number> numberList = new ArrayList<>();
        addNumbers(numberList);
        System.out.println("Number列表: " + numberList);
        
        // 无界通配符
        printListSize(intList);
        printListSize(stringList);
        
        // 泛型限制示例
        GenericRestrictionDemo();
    }
    
    // 上界通配符:? extends Number
    public static void printNumbers(List<? extends Number> list) {
        for (Number num : list) {
            System.out.println("数字: " + num.doubleValue());
        }
    }
    
    // 下界通配符:? super Integer
    public static void addNumbers(List<? super Integer> list) {
        list.add(1);
        list.add(2);
        list.add(3);
    }
    
    // 无界通配符:?
    public static void printListSize(List<?> list) {
        System.out.println("列表大小: " + list.size());
    }
    
    public static void GenericRestrictionDemo() {
        // 泛型擦除示例
        List<String> stringList = new ArrayList<>();
        List<Integer> integerList = new ArrayList<>();
        
        // 运行时类型相同
        System.out.println("类型相同: " + 
            (stringList.getClass() == integerList.getClass()));
        
        // 多重限制
        processComparableAndSerializable("Hello");
        processComparableAndSerializable(42);
    }
    
    // 多重限制T必须既实现Comparable又实现Serializable
    public static <T extends Comparable<T> & java.io.Serializable> void 
           processComparableAndSerializable(T item) {
        System.out.println("处理项目: " + item);
        System.out.println("可比较: " + (item instanceof Comparable));
        System.out.println("可序列化: " + (item instanceof java.io.Serializable));
    }
}

注解

16.1 内置注解

// @Override标记重写方法
class Animal {
    public void makeSound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("狗汪汪叫");
    }
}

// @Deprecated标记过时的方法
class Calculator {
    @Deprecated
    public int oldAdd(int a, int b) {
        return a + b;
    }
    
    public int add(int a, int b) {
        return a + b;
    }
}

// @SuppressWarnings抑制警告
public class AnnotationDemo {
    @SuppressWarnings("unchecked")
    public static void rawTypeExample() {
        List list = new ArrayList();  // 原始类型,会有警告
        list.add("hello");
        list.add(123);
    }
    
    @SuppressWarnings({"unused", "deprecation"})
    public static void suppressMultipleWarnings() {
        int unusedVariable = 10;
        Calculator calc = new Calculator();
        int result = calc.oldAdd(1, 2);  // 使用过时方法
    }
}

16.2 自定义注解

import java.lang.annotation.*;

// 定义注解
@Target(ElementType.METHOD)  // 作用于方法
@Retention(RetentionPolicy.RUNTIME)  // 运行时可获取
@Documented  // 包含在javadoc中
public @interface TestMethod {
    String description() default "";
    int timeout() default 5000;
    boolean enabled() default true;
}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
    String name();
    String email() default "";
    String date();
}

// 使用自定义注解
@Author(name = "张三", email = "zhangsan@example.com", date = "2024-01-01")
public class MyTestClass {
    
    @TestMethod(description = "测试加法运算", timeout = 3000)
    public void testAdd() {
        System.out.println("执行加法测试");
    }
    
    @TestMethod(description = "测试除法运算", enabled = false)
    public void testDivide() {
        System.out.println("执行除法测试");
    }
    
    @TestMethod
    public void testDefault() {
        System.out.println("使用默认参数的测试");
    }
    
    public void normalMethod() {
        System.out.println("普通方法,没有注解");
    }
}

16.3 注解处理

import java.lang.reflect.*;

public class AnnotationProcessor {
    public static void main(String[] args) {
        processClass(MyTestClass.class);
    }
    
    public static void processClass(Class<?> clazz) {
        // 处理类级别注解
        if (clazz.isAnnotationPresent(Author.class)) {
            Author author = clazz.getAnnotation(Author.class);
            System.out.println("作者信息:");
            System.out.println("  姓名: " + author.name());
            System.out.println("  邮箱: " + author.email());
            System.out.println("  日期: " + author.date());
            System.out.println();
        }
        
        // 处理方法级别注解
        Method[] methods = clazz.getDeclaredMethods();
        
        for (Method method : methods) {
            if (method.isAnnotationPresent(TestMethod.class)) {
                TestMethod testMethod = method.getAnnotation(TestMethod.class);
                
                System.out.println("测试方法: " + method.getName());
                System.out.println("  描述: " + testMethod.description());
                System.out.println("  超时: " + testMethod.timeout() + "ms");
                System.out.println("  启用: " + testMethod.enabled());
                
                if (testMethod.enabled()) {
                    try {
                        // 创建实例并调用方法
                        Object instance = clazz.getDeclaredConstructor().newInstance();
                        method.invoke(instance);
                        System.out.println("  执行结果: 成功");
                    } catch (Exception e) {
                        System.out.println("  执行结果: 失败 - " + e.getMessage());
                    }
                } else {
                    System.out.println("  执行结果: 跳过(已禁用)");
                }
                System.out.println();
            }
        }
    }
}

Lambda表达式

17.1 Lambda基础语法

import java.util.*;
import java.util.function.*;

public class LambdaBasics {
    public static void main(String[] args) {
        // 1. 无参数Lambda
        Runnable task1 = () -> System.out.println("Hello Lambda!");
        task1.run();
        
        // 2. 单参数Lambda可省略括号
        Consumer<String> printer = message -> System.out.println("消息: " + message);
        printer.accept("Lambda表达式");
        
        // 3. 多参数Lambda
        BinaryOperator<Integer> adder = (a, b) -> a + b;
        System.out.println("5 + 3 = " + adder.apply(5, 3));
        
        // 4. 有返回值的Lambda
        Function<String, Integer> lengthCalculator = str -> str.length();
        System.out.println("字符串长度: " + lengthCalculator.apply("Hello"));
        
        // 5. 多行Lambda
        Function<List<Integer>, Integer> sumCalculator = list -> {
            int sum = 0;
            for (int num : list) {
                sum += num;
            }
            return sum;
        };
        
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        System.out.println("列表总和: " + sumCalculator.apply(numbers));
        
        // 6. 方法引用
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        
        // Lambda表达式
        words.forEach(word -> System.out.println(word));
        
        // 方法引用(等价)
        words.forEach(System.out::println);
        
        // 静态方法引用
        Function<String, Integer> parseInt = Integer::parseInt;
        System.out.println("解析数字: " + parseInt.apply("42"));
        
        // 实例方法引用
        String text = "Hello World";
        Supplier<String> upperCase = text::toUpperCase;
        System.out.println("大写: " + upperCase.get());
        
        // 构造方法引用
        Supplier<List<String>> listSupplier = ArrayList::new;
        List<String> newList = listSupplier.get();
    }
}

17.2 函数式接口

// 自定义函数式接口
@FunctionalInterface
public interface MathOperation {
    int operate(int a, int b);
    
    // 可以有默认方法
    default void printResult(int a, int b) {
        System.out.println("结果: " + operate(a, b));
    }
    
    // 可以有静态方法
    static void printInfo() {
        System.out.println("这是一个数学运算接口");
    }
}

// 内置函数式接口使用
import java.util.function.*;

public class FunctionalInterfaceDemo {
    public static void main(String[] args) {
        // Consumer<T>:接受一个参数,无返回值
        Consumer<String> stringConsumer = str -> System.out.println("处理: " + str);
        stringConsumer.accept("测试字符串");
        
        // Supplier<T>:无参数,返回一个值
        Supplier<Double> randomSupplier = () -> Math.random();
        System.out.println("随机数: " + randomSupplier.get());
        
        // Function<T, R>:接受一个参数,返回一个值
        Function<String, Integer> stringLength = String::length;
        System.out.println("长度: " + stringLength.apply("Hello"));
        
        // Predicate<T>接受一个参数返回boolean
        Predicate<Integer> isEven = num -> num % 2 == 0;
        System.out.println("8是偶数: " + isEven.test(8));
        System.out.println("7是偶数: " + isEven.test(7));
        
        // BiFunction<T, U, R>:接受两个参数,返回一个值
        BiFunction<String, String, String> concatenator = (s1, s2) -> s1 + " " + s2;
        System.out.println("拼接: " + concatenator.apply("Hello", "World"));
        
        // UnaryOperator<T>:接受一个参数,返回同类型值
        UnaryOperator<String> upperCase = String::toUpperCase;
        System.out.println("大写: " + upperCase.apply("hello"));
        
        // BinaryOperator<T>:接受两个同类型参数,返回同类型值
        BinaryOperator<Integer> maxOperator = Integer::max;
        System.out.println("最大值: " + maxOperator.apply(10, 20));
        
        // 使用自定义函数式接口
        MathOperation addition = (a, b) -> a + b;
        MathOperation multiplication = (a, b) -> a * b;
        
        System.out.println("加法: " + calculate(5, 3, addition));
        System.out.println("乘法: " + calculate(5, 3, multiplication));
        
        // Predicate组合
        Predicate<Integer> isPositive = num -> num > 0;
        Predicate<Integer> isLessThan100 = num -> num < 100;
        Predicate<Integer> isInRange = isPositive.and(isLessThan100);
        
        System.out.println("50在范围内: " + isInRange.test(50));
        System.out.println("-5在范围内: " + isInRange.test(-5));
        System.out.println("150在范围内: " + isInRange.test(150));
    }
    
    public static int calculate(int a, int b, MathOperation operation) {
        return operation.operate(a, b);
    }
}

Stream API

18.1 Stream基础操作

import java.util.*;
import java.util.stream.*;

public class StreamBasics {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        // 1. 创建Stream
        // 从集合创建
        Stream<Integer> stream1 = numbers.stream();
        
        // 从数组创建
        String[] words = {"apple", "banana", "cherry"};
        Stream<String> stream2 = Arrays.stream(words);
        
        // 使用Stream.of()创建
        Stream<String> stream3 = Stream.of("a", "b", "c");
        
        // 生成Stream
        Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2).limit(10);
        Stream<Double> randomStream = Stream.generate(Math::random).limit(5);
        
        // 2. 中间操作Intermediate Operations
        
        // filter过滤
        List<Integer> evenNumbers = numbers.stream()
            .filter(n -> n % 2 == 0)
            .collect(Collectors.toList());
        System.out.println("偶数: " + evenNumbers);
        
        // map转换
        List<String> squareStrings = numbers.stream()
            .map(n -> n * n)
            .map(String::valueOf)
            .collect(Collectors.toList());
        System.out.println("平方字符串: " + squareStrings);
        
        // distinct去重
        List<Integer> duplicates = Arrays.asList(1, 2, 2, 3, 3, 3, 4);
        List<Integer> unique = duplicates.stream()
            .distinct()
            .collect(Collectors.toList());
        System.out.println("去重: " + unique);
        
        // sorted排序
        List<String> fruits = Arrays.asList("banana", "apple", "cherry", "date");
        List<String> sortedFruits = fruits.stream()
            .sorted()
            .collect(Collectors.toList());
        System.out.println("排序: " + sortedFruits);
        
        // 自定义排序
        List<String> sortedByLength = fruits.stream()
            .sorted(Comparator.comparing(String::length))
            .collect(Collectors.toList());
        System.out.println("按长度排序: " + sortedByLength);
        
        // limit和skip限制和跳过
        List<Integer> limitedNumbers = numbers.stream()
            .skip(3)
            .limit(4)
            .collect(Collectors.toList());
        System.out.println("跳过3个取4个: " + limitedNumbers);
        
        // 3. 终端操作Terminal Operations
        
        // forEach遍历
        System.out.print("遍历输出: ");
        numbers.stream()
            .filter(n -> n <= 5)
            .forEach(n -> System.out.print(n + " "));
        System.out.println();
        
        // collect收集
        Set<Integer> numberSet = numbers.stream()
            .collect(Collectors.toSet());
        System.out.println("转为Set: " + numberSet);
        
        // reduce归约
        Optional<Integer> sum = numbers.stream()
            .reduce(Integer::sum);
        System.out.println("总和: " + sum.orElse(0));
        
        int product = numbers.stream()
            .reduce(1, (a, b) -> a * b);
        System.out.println("乘积: " + product);
        
        // count计数
        long count = numbers.stream()
            .filter(n -> n > 5)
            .count();
        System.out.println("大于5的数量: " + count);
        
        // anyMatch, allMatch, noneMatch匹配
        boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0);
        boolean allPositive = numbers.stream().allMatch(n -> n > 0);
        boolean noneNegative = numbers.stream().noneMatch(n -> n < 0);
        
        System.out.println("有偶数: " + hasEven);
        System.out.println("全为正数: " + allPositive);
        System.out.println("没有负数: " + noneNegative);
        
        // findFirst, findAny查找
        Optional<Integer> first = numbers.stream()
            .filter(n -> n > 5)
            .findFirst();
        System.out.println("第一个大于5: " + first.orElse(-1));
        
        // min, max最值
        Optional<Integer> min = numbers.stream().min(Integer::compareTo);
        Optional<Integer> max = numbers.stream().max(Integer::compareTo);
        System.out.println("最小值: " + min.orElse(-1));
        System.out.println("最大值: " + max.orElse(-1));
    }
}

18.2 复杂Stream操作

// 学生类
class Student {
    private String name;
    private int age;
    private String gender;
    private double score;
    private String subject;
    
    public Student(String name, int age, String gender, double score, String subject) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.score = score;
        this.subject = subject;
    }
    
    // getters和toString方法...
    public String getName() { return name; }
    public int getAge() { return age; }
    public String getGender() { return gender; }
    public double getScore() { return score; }
    public String getSubject() { return subject; }
    
    @Override
    public String toString() {
        return String.format("Student{name='%s', age=%d, gender='%s', score=%.1f, subject='%s'}", 
                           name, age, gender, score, subject);
    }
}

public class AdvancedStreamOperations {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
            new Student("张三", 20, "男", 85.5, "数学"),
            new Student("李四", 21, "女", 92.0, "英语"),
            new Student("王五", 19, "男", 78.5, "数学"),
            new Student("赵六", 22, "女", 88.0, "物理"),
            new Student("陈七", 20, "男", 95.5, "英语"),
            new Student("刘八", 21, "女", 82.0, "物理")
        );
        
        // 1. 分组操作
        Map<String, List<Student>> bySubject = students.stream()
            .collect(Collectors.groupingBy(Student::getSubject));
        
        System.out.println("按科目分组:");
        bySubject.forEach((subject, studentList) -> {
            System.out.println(subject + ": " + studentList.size() + "人");
        });
        
        // 2. 分组并统计
        Map<String, Double> avgScoreBySubject = students.stream()
            .collect(Collectors.groupingBy(
                Student::getSubject,
                Collectors.averagingDouble(Student::getScore)
            ));
        
        System.out.println("\n各科目平均分:");
        avgScoreBySubject.forEach((subject, avgScore) -> 
            System.out.printf("%s: %.2f\n", subject, avgScore));
        
        // 3. 分区操作
        Map<Boolean, List<Student>> partitionByGender = students.stream()
            .collect(Collectors.partitioningBy(s -> "男".equals(s.getGender())));
        
        System.out.println("\n按性别分区:");
        System.out.println("男生: " + partitionByGender.get(true).size() + "人");
        System.out.println("女生: " + partitionByGender.get(false).size() + "人");
        
        // 4. 复杂统计
        DoubleSummaryStatistics scoreStats = students.stream()
            .mapToDouble(Student::getScore)
            .summaryStatistics();
        
        System.out.println("\n成绩统计:");
        System.out.printf("平均分: %.2f\n", scoreStats.getAverage());
        System.out.printf("最高分: %.1f\n", scoreStats.getMax());
        System.out.printf("最低分: %.1f\n", scoreStats.getMin());
        System.out.printf("总分: %.1f\n", scoreStats.getSum());
        System.out.println("人数: " + scoreStats.getCount());
        
        // 5. 多级分组
        Map<String, Map<String, List<Student>>> multiGroup = students.stream()
            .collect(Collectors.groupingBy(
                Student::getSubject,
                Collectors.groupingBy(Student::getGender)
            ));
        
        System.out.println("\n多级分组科目-性别):");
        multiGroup.forEach((subject, genderMap) -> {
            System.out.println(subject + ":");
            genderMap.forEach((gender, studentList) -> 
                System.out.println("  " + gender + ": " + studentList.size() + "人"));
        });
        
        // 6. 自定义收集器
        String studentNames = students.stream()
            .map(Student::getName)
            .collect(Collectors.joining(", ", "[", "]"));
        System.out.println("\n学生姓名: " + studentNames);
        
        // 7. 排序和查找
        System.out.println("\n成绩前3名:");
        students.stream()
            .sorted(Comparator.comparing(Student::getScore).reversed())
            .limit(3)
            .forEach(System.out::println);
        
        // 8. 复合条件查询
        System.out.println("\n数学科目且成绩大于80分的学生:");
        students.stream()
            .filter(s -> "数学".equals(s.getSubject()))
            .filter(s -> s.getScore() > 80)
            .forEach(System.out::println);
        
        // 9. flatMap操作
        List<List<String>> nestedList = Arrays.asList(
            Arrays.asList("a", "b"),
            Arrays.asList("c", "d", "e"),
            Arrays.asList("f")
        );
        
        List<String> flatList = nestedList.stream()
            .flatMap(List::stream)
            .collect(Collectors.toList());
        System.out.println("\n扁平化列表: " + flatList);
        
        // 10. 并行流
        long parallelSum = students.parallelStream()
            .mapToDouble(Student::getScore)
            .sum();
        System.out.println("\n并行计算总分: " + parallelSum);
    }
}

总结

这份Java语法指南涵盖了Java编程的核心概念和高级特性

基础部分

  • 数据类型、变量、运算符
  • 控制结构、数组、方法

面向对象

  • 类与对象、封装、继承、多态
  • 接口与抽象类

高级特性

  • 异常处理、集合框架、IO操作
  • 多线程、泛型、注解
  • Lambda表达式、Stream API

学习建议

  1. 循序渐进:从基础语法开始,逐步掌握高级特性
  2. 多加练习:通过编写代码加深理解
  3. 项目实战:将知识点应用到实际项目中
  4. 持续学习Java生态系统丰富需要不断学习新技术

Java是一门功能强大的编程语言掌握这些语法特性将为你的编程之路打下坚实基础