2807 lines
79 KiB
Markdown
2807 lines
79 KiB
Markdown
# Java 语法完整指南
|
||
|
||
## 目录
|
||
1. [Java基础概念](#java基础概念)
|
||
2. [数据类型](#数据类型)
|
||
3. [变量与常量](#变量与常量)
|
||
4. [运算符](#运算符)
|
||
5. [控制结构](#控制结构)
|
||
6. [数组](#数组)
|
||
7. [方法](#方法)
|
||
8. [面向对象编程](#面向对象编程)
|
||
9. [接口与抽象类](#接口与抽象类)
|
||
10. [异常处理](#异常处理)
|
||
11. [集合框架](#集合框架)
|
||
12. [字符串处理](#字符串处理)
|
||
13. [文件IO](#文件io)
|
||
14. [多线程](#多线程)
|
||
15. [泛型](#泛型)
|
||
16. [注解](#注解)
|
||
17. [Lambda表达式](#lambda表达式)
|
||
18. [Stream API](#stream-api)
|
||
|
||
---
|
||
|
||
## Java基础概念
|
||
|
||
### 1.1 Java程序结构
|
||
```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 编译与运行
|
||
```bash
|
||
# 编译Java源文件
|
||
javac HelloWorld.java
|
||
|
||
# 运行Java程序
|
||
java HelloWorld
|
||
```
|
||
|
||
### 1.3 Java特性
|
||
- **面向对象**:封装、继承、多态
|
||
- **平台无关性**:一次编写,到处运行
|
||
- **自动内存管理**:垃圾回收机制
|
||
- **强类型检查**:编译时类型检查
|
||
- **多线程支持**:内置多线程支持
|
||
|
||
---
|
||
|
||
## 数据类型
|
||
|
||
### 2.1 基本数据类型
|
||
```java
|
||
// 整型
|
||
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 引用数据类型
|
||
```java
|
||
// 字符串
|
||
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 类型转换
|
||
```java
|
||
// 自动类型转换(小范围到大范围)
|
||
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 变量声明
|
||
```java
|
||
// 变量声明语法:数据类型 变量名 = 初始值;
|
||
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 常量定义
|
||
```java
|
||
// 使用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 变量命名规范
|
||
```java
|
||
// 良好的命名示例
|
||
int studentAge; // 驼峰命名法
|
||
String firstName; // 驼峰命名法
|
||
boolean isValid; // 布尔值用is开头
|
||
final int MAX_COUNT = 50; // 常量用大写+下划线
|
||
|
||
// 避免的命名
|
||
int a, b, c; // 无意义的名称
|
||
String s1, s2; // 无意义的名称
|
||
```
|
||
|
||
---
|
||
|
||
## 运算符
|
||
|
||
### 4.1 算术运算符
|
||
```java
|
||
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 关系运算符
|
||
```java
|
||
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 逻辑运算符
|
||
```java
|
||
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 位运算符
|
||
```java
|
||
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 赋值运算符
|
||
```java
|
||
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 三元运算符
|
||
```java
|
||
int a = 10, b = 5;
|
||
int max = (a > b) ? a : b; // 如果a>b则取a,否则取b
|
||
|
||
String result = (score >= 60) ? "及格" : "不及格";
|
||
```
|
||
|
||
---
|
||
|
||
## 控制结构
|
||
|
||
### 5.1 条件语句
|
||
|
||
#### if语句
|
||
```java
|
||
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语句
|
||
```java
|
||
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循环
|
||
```java
|
||
// 基本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循环
|
||
```java
|
||
int i = 0;
|
||
while (i < 5) {
|
||
System.out.println("i = " + i);
|
||
i++;
|
||
}
|
||
|
||
// 无限循环
|
||
while (true) {
|
||
// 某些条件下break
|
||
if (condition) {
|
||
break;
|
||
}
|
||
}
|
||
```
|
||
|
||
#### do-while循环
|
||
```java
|
||
int i = 0;
|
||
do {
|
||
System.out.println("i = " + i);
|
||
i++;
|
||
} while (i < 5);
|
||
```
|
||
|
||
### 5.3 跳转语句
|
||
```java
|
||
// 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 一维数组
|
||
```java
|
||
// 数组声明和初始化
|
||
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 二维数组
|
||
```java
|
||
// 二维数组声明和初始化
|
||
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 数组常用操作
|
||
```java
|
||
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 方法定义和调用
|
||
```java
|
||
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 方法重载
|
||
```java
|
||
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 可变参数
|
||
```java
|
||
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 递归方法
|
||
```java
|
||
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 类和对象
|
||
```java
|
||
// 类定义
|
||
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 封装
|
||
```java
|
||
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 继承
|
||
```java
|
||
// 父类(基类)
|
||
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 多态
|
||
```java
|
||
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 接口
|
||
```java
|
||
// 接口定义
|
||
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 抽象类
|
||
```java
|
||
// 抽象类定义
|
||
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
|
||
// Java异常层次结构
|
||
/*
|
||
Throwable
|
||
├── Error(错误)
|
||
│ ├── OutOfMemoryError
|
||
│ ├── StackOverflowError
|
||
│ └── ...
|
||
└── Exception(异常)
|
||
├── RuntimeException(运行时异常,非检查异常)
|
||
│ ├── NullPointerException
|
||
│ ├── ArrayIndexOutOfBoundsException
|
||
│ ├── IllegalArgumentException
|
||
│ └── ...
|
||
└── 检查异常
|
||
├── IOException
|
||
├── ClassNotFoundException
|
||
└── ...
|
||
*/
|
||
```
|
||
|
||
### 10.2 异常处理语法
|
||
```java
|
||
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-resources(Java 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 自定义异常
|
||
```java
|
||
// 自定义异常类
|
||
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 异常传播和处理最佳实践
|
||
```java
|
||
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接口
|
||
```java
|
||
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接口
|
||
```java
|
||
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接口
|
||
```java
|
||
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());
|
||
}
|
||
|
||
// 方法3:Java 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工具类
|
||
```java
|
||
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类
|
||
```java
|
||
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
|
||
```java
|
||
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 正则表达式
|
||
```java
|
||
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 文件操作基础
|
||
```java
|
||
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 字符流操作
|
||
```java
|
||
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 字节流操作
|
||
```java
|
||
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文件操作
|
||
```java
|
||
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 创建线程
|
||
```java
|
||
// 方法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 线程同步
|
||
```java
|
||
// 同步问题示例
|
||
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 线程通信
|
||
```java
|
||
// 生产者-消费者模式
|
||
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 线程池
|
||
```java
|
||
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 泛型基础
|
||
```java
|
||
// 泛型类
|
||
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 泛型通配符
|
||
```java
|
||
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 内置注解
|
||
```java
|
||
// @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 自定义注解
|
||
```java
|
||
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 注解处理
|
||
```java
|
||
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基础语法
|
||
```java
|
||
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 函数式接口
|
||
```java
|
||
// 自定义函数式接口
|
||
@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基础操作
|
||
```java
|
||
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操作
|
||
```java
|
||
// 学生类
|
||
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是一门功能强大的编程语言,掌握这些语法特性将为你的编程之路打下坚实基础! |