Java SE 学习笔记
本文档基于狂神说Java整理完善,涵盖Java SE核心知识点
目录
- Java基础
- Java语法基础
- 流程控制
- 数组
- 面向对象编程
- 异常处理
- 常用类
- 集合框架
- 泛型
- IO流
- 多线程
- 网络编程
- 反射机制
- 注解
- Lambda表达式与Stream API
一、Java基础
1.1 Java三大版本
| 版本 |
全称 |
说明 |
| Java SE |
Standard Edition(标准版) |
Java的核心版本,提供基础类库(集合、IO、多线程等),用于开发桌面应用 |
| Java EE |
Enterprise Edition(企业版) |
用于开发大型企业级应用(网站、分布式系统),现多使用Spring框架 |
| Java ME |
Micro Edition(嵌入式版) |
用于资源受限设备,现已较少使用 |
1.2 JDK、JRE、JVM
┌─────────────────────────────────────┐
│ JDK │
│ ┌─────────────────────────────┐ │
│ │ JRE │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ JVM │ │ │
│ │ │ (Java虚拟机) │ │ │
│ │ └─────────────────────┘ │ │
│ │ + 核心类库(运行所需) │ │
│ └─────────────────────────────┘ │
│ + 开发工具(javac、java、javadoc) │
└─────────────────────────────────────┘
关系:JDK > JRE > JVM
| 组件 |
说明 |
| JVM |
Java虚拟机,负责运行.class字节码文件,实现"一次编写,到处运行" |
| JRE |
Java运行环境,包含JVM + 核心类库 |
| JDK |
Java开发工具包,包含JRE + 开发工具 |
1.3 Java环境搭建
# 1. 配置环境变量
JAVA_HOME = C:\Program Files\Java\jdk-xx
PATH = %JAVA_HOME%\bin
# 2. 验证安装
java -version
javac -version
1.4 第一个Java程序
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
编译与运行:
javac HelloWorld.java # 编译,生成 HelloWorld.class
java HelloWorld # 运行
1.5 Java程序运行机制
Java是编译型 + 解释型的混合语言:
.java源文件 → [javac编译] → .class字节码 → [JVM解释执行] → 机器码
二、Java语法基础
2.1 标识符与关键字
标识符规则:
- 由字母、数字、下划线
_、美元符$组成
- 不能以数字开头
- 区分大小写
- 不能使用关键字
常用关键字:
| 类别 |
关键字 |
| 访问控制 |
private, protected, public |
| 类/方法/变量 |
class, interface, abstract, static, final |
| 流程控制 |
if, else, switch, case, for, while, do, break, continue, return |
| 异常处理 |
try, catch, finally, throw, throws |
| 其他 |
extends, implements, import, package, this, super, new, instanceof |
2.2 数据类型
基本数据类型(8种)
| 类型 |
占用字节 |
默认值 |
取值范围 |
byte |
1 |
0 |
-128 ~ 127 |
short |
2 |
0 |
-32768 ~ 32767 |
int |
4 |
0 |
-2³¹ ~ 2³¹-1 |
long |
8 |
0L |
-2⁶³ ~ 2⁶³-1 |
float |
4 |
0.0f |
约 ±3.4E-38 ~ ±3.4E+38 |
double |
8 |
0.0d |
约 ±1.7E-308 ~ ±1.7E+308 |
char |
2 |
'\u0000' |
0 ~ 65535 |
boolean |
1 bit |
false |
true / false |
引用数据类型
- 类(Class)
- 接口(Interface)
- 数组(Array)
2.3 类型转换
// 自动类型转换(低 → 高)
int a = 10;
double b = a; // 自动转换,b = 10.0
// 强制类型转换(高 → 低)
double c = 10.5;
int d = (int)c; // 强制转换,d = 10(精度丢失)
// 注意
// 1. boolean不能转换
// 2. 高转低可能溢出或精度丢失
类型提升顺序:byte → short → char → int → long → float → double
2.4 变量
public class VariableDemo {
// 实例变量(成员变量)
private int instanceVar = 10;
// 类变量(静态变量)
private static int staticVar = 20;
// 常量
private static final int MAX_SIZE = 100;
public void method() {
// 局部变量
int localVar = 30;
System.out.println(localVar);
}
}
| 变量类型 |
定义位置 |
作用域 |
默认值 |
| 局部变量 |
方法内部 |
方法内 |
必须初始化 |
| 实例变量 |
类中,方法外 |
对象内 |
数值0,布尔false,引用null |
| 类变量 |
类中,static修饰 |
整个类 |
同实例变量 |
2.5 运算符
| 类型 |
运算符 |
| 算术 |
+, -, *, /, %, ++, -- |
| 赋值 |
=, +=, -=, *=, /=, %= |
| 比较 |
==, !=, >, <, >=, <= |
| 逻辑 |
&&, ||, ! |
| 位运算 |
&, |, ^, ~, <<, >>, >>> |
| 三元 |
? : |
2.6 包机制
// 声明包(必须在文件第一行)
package com.example.demo;
// 导入包
import java.util.Scanner;
import java.util.*; // 导入util包下所有类
import static java.lang.Math.*; // 静态导入
命名规范:域名倒写 + 项目名 + 模块名,如 com.company.project.module
2.7 JavaDoc注释
/**
* 类说明:用户实体类
* @author 作者名
* @version 1.0
* @since 1.8
*/
public class User {
/**
* 获取用户名
* @param id 用户ID
* @return 用户名
* @throws Exception 当用户不存在时抛出
*/
public String getUsername(int id) throws Exception {
return "username";
}
}
生成命令:javadoc -d doc -author -version User.java
三、流程控制
3.1 用户交互Scanner
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取字符串
System.out.print("请输入姓名:");
String name = scanner.nextLine();
// 读取整数
System.out.print("请输入年龄:");
int age = scanner.nextInt();
// 读取小数
System.out.print("请输入成绩:");
double score = scanner.nextDouble();
System.out.println("姓名:" + name + ",年龄:" + age + ",成绩:" + score);
scanner.close(); // 关闭资源
}
}
常用方法:
| 方法 |
说明 |
next() |
读取字符串(以空格为分隔) |
nextLine() |
读取一行字符串 |
nextInt() |
读取整数 |
nextDouble() |
读取小数 |
nextBoolean() |
读取布尔值 |
3.2 选择结构
// if-else if-else
int score = 85;
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 12+支持箭头语法)
int day = 3;
switch (day) {
case 1 -> System.out.println("星期一");
case 2 -> System.out.println("星期二");
case 3 -> System.out.println("星期三");
default -> System.out.println("其他");
}
3.3 循环结构
// for循环
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
// while循环
int i = 0;
while (i < 5) {
System.out.println(i);
i++;
}
// do-while循环(至少执行一次)
int j = 0;
do {
System.out.println(j);
j++;
} while (j < 5);
// 增强for循环(for-each)
int[] nums = {1, 2, 3, 4, 5};
for (int num : nums) {
System.out.println(num);
}
3.4 跳转语句
| 语句 |
作用 |
break |
跳出当前循环或switch |
continue |
跳过当前迭代,进入下一次循环 |
return |
结束方法执行 |
// break示例:找到第一个能被3和5整除的数
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0 && i % 5 == 0) {
System.out.println("找到:" + i); // 15
break;
}
}
// continue示例:跳过奇数
for (int i = 1; i <= 10; i++) {
if (i % 2 != 0) continue;
System.out.println(i); // 2, 4, 6, 8, 10
}
四、数组
4.1 数组声明与创建
// 声明
int[] nums;
// 创建
nums = new int[5];
// 声明+创建
int[] nums = new int[5];
// 静态初始化
int[] nums = {1, 2, 3, 4, 5};
String[] names = new String[]{"Alice", "Bob", "Charlie"};
4.2 数组操作
int[] arr = {5, 2, 8, 1, 9};
// 访问元素
System.out.println(arr[0]); // 5
// 修改元素
arr[1] = 10;
// 获取长度
System.out.println(arr.length); // 5
// 遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
// for-each遍历
for (int num : arr) {
System.out.println(num);
}
4.3 多维数组
// 二维数组
int[][] matrix = new int[3][4];
// 静态初始化
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 遍历二维数组
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
4.4 Arrays工具类
import java.util.Arrays;
int[] arr = {3, 1, 4, 1, 5, 9};
// 打印数组
System.out.println(Arrays.toString(arr)); // [3, 1, 4, 1, 5, 9]
// 排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr)); // [1, 1, 3, 4, 5, 9]
// 二分查找(数组必须先排序)
int index = Arrays.binarySearch(arr, 4); // 返回索引3
// 填充数组
Arrays.fill(arr, 0); // 所有元素变为0
// 复制数组
int[] copy = Arrays.copyOf(arr, arr.length);
// 比较数组
boolean equal = Arrays.equals(arr, copy);
4.5 稀疏数组
用于存储大部分元素为0或相同值的数组,节省空间。
// 原始数组(11x11棋盘,2个棋子)
int[][] chess = new int[11][11];
chess[1][2] = 1; // 黑棋
chess[2][3] = 2; // 白棋
// 转换为稀疏数组
int sum = 0;
for (int[] row : chess) {
for (int val : row) {
if (val != 0) sum++;
}
}
int[][] sparse = new int[sum + 1][3];
sparse[0][0] = 11; // 行数
sparse[0][1] = 11; // 列数
sparse[0][2] = sum; // 有效数据个数
int count = 1;
for (int i = 0; i < chess.length; i++) {
for (int j = 0; j < chess[i].length; j++) {
if (chess[i][j] != 0) {
sparse[count][0] = i;
sparse[count][1] = j;
sparse[count][2] = chess[i][j];
count++;
}
}
}
五、面向对象编程
5.1 类与对象
// 定义类
public class Student {
// 属性(成员变量)
private String name;
private int age;
// 构造方法
public Student() {} // 无参构造
public Student(String name, int age) { // 有参构造
this.name = name;
this.age = age;
}
// 方法
public void study() {
System.out.println(name + "在学习");
}
// getter/setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
// 创建对象
Student stu = new Student("张三", 18);
stu.study();
5.2 三大特性
封装(Encapsulation)
public class Person {
private String name; // 私有属性
private int age;
// 公共的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;
} else {
System.out.println("年龄不合法");
}
}
}
继承(Inheritance)
// 父类
public class Animal {
protected String name;
public void eat() {
System.out.println("动物在吃东西");
}
}
// 子类
public class Dog extends Animal {
public void bark() {
System.out.println(name + "汪汪叫");
}
@Override
public void eat() {
System.out.println(name + "在吃骨头");
}
}
继承特点:
- Java只支持单继承
- 支持多层继承
- 子类继承父类非私有成员
多态(Polymorphism)
// 父类引用指向子类对象
Animal animal = new Dog();
animal.eat(); // 调用Dog的eat方法
// 多态的应用
public void feed(Animal animal) {
animal.eat();
}
feed(new Dog()); // 喂狗
feed(new Cat()); // 喂猫
多态前提:
- 有继承关系
- 有方法重写
- 父类引用指向子类对象
5.3 关键字详解
this vs super
| 关键字 |
含义 |
用法 |
this |
当前对象 |
this.属性, this.方法(), this()调用构造 |
super |
父类对象 |
super.属性, super.方法(), super()调用父类构造 |
public class Student extends Person {
private String school;
public Student(String name, int age, String school) {
super(name, age); // 调用父类构造
this.school = school; // 访问当前类属性
}
}
static
public class StaticDemo {
// 静态变量(类变量)
static int count = 0;
// 实例变量
int num = 0;
// 静态代码块(类加载时执行,只执行一次)
static {
System.out.println("静态代码块");
}
// 匿名代码块(每次创建对象执行)
{
System.out.println("匿名代码块");
}
// 静态方法
public static void staticMethod() {
System.out.println("静态方法");
// 只能访问静态成员
}
}
执行顺序:静态代码块 → 匿名代码块 → 构造方法
final
| 用法 |
说明 |
final变量 |
常量,只能赋值一次 |
final方法 |
不能被子类重写 |
final类 |
不能被继承 |
5.4 抽象类与接口
抽象类
// 抽象类
public abstract class Shape {
protected String color;
// 普通方法
public void setColor(String color) {
this.color = color;
}
// 抽象方法(子类必须实现)
public abstract double getArea();
}
// 子类实现
public class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}
接口
// 定义接口
public interface Flyable {
// 常量(默认public static final)
int MAX_HEIGHT = 10000;
// 抽象方法(默认public abstract)
void fly();
// 默认方法(Java 8+)
default void land() {
System.out.println("降落");
}
// 静态方法(Java 8+)
static void check() {
System.out.println("检查飞行状态");
}
}
// 实现接口
public class Bird implements Flyable {
@Override
public void fly() {
System.out.println("鸟在飞");
}
}
抽象类 vs 接口:
| 特性 |
抽象类 |
接口 |
| 继承 |
单继承 |
多实现 |
| 构造方法 |
有 |
无 |
| 成员变量 |
可以有各种类型 |
只能是public static final |
| 方法 |
可以有具体方法 |
Java 8前只能抽象 |
| 设计目的 |
"是什么"(is-a) |
"能做什么"(can-do) |
5.5 内部类
public class Outer {
private int num = 10;
// 成员内部类
class Inner {
public void show() {
System.out.println(num); // 访问外部类成员
}
}
// 静态内部类
static class StaticInner {
public void show() {
System.out.println("静态内部类");
}
}
public void method() {
// 局部内部类
class LocalInner {
public void show() {
System.out.println("局部内部类");
}
}
}
}
// 匿名内部类
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("运行");
}
};
5.6 方法详解
方法重载(Overload)
public class Calculator {
// 方法名相同,参数不同
public int add(int a, int b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
public double add(double a, double b) {
return a + b;
}
}
方法重写(Override)
class Animal {
public void move() {
System.out.println("动物移动");
}
}
class Dog extends Animal {
@Override
public void move() {
System.out.println("狗在跑");
}
}
重写规则:
- 方法名、参数列表相同
- 返回类型兼容
- 访问修饰符不能更严格
- 异常不能扩大
可变参数
public void printNumbers(int... nums) {
for (int num : nums) {
System.out.println(num);
}
}
// 调用
printNumbers(1, 2, 3);
printNumbers(1, 2, 3, 4, 5);
递归
// 阶乘
public int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
// 斐波那契
public int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
六、异常处理
6.1 异常体系
Throwable
├── Error(严重错误,不处理)
│ ├── OutOfMemoryError
│ └── StackOverflowError
└── Exception(可以处理)
├── RuntimeException(运行时异常,不强制处理)
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ └── ClassCastException
└── Checked Exception(编译时异常,必须处理)
├── IOException
└── SQLException
6.2 异常处理
// try-catch-finally
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("除数不能为0");
} catch (Exception e) {
System.out.println("其他异常");
} finally {
System.out.println("最终执行");
}
// 多个catch合并(Java 7+)
try {
// 可能抛出异常的代码
} catch (IOException | SQLException e) {
System.out.println("IO或SQL异常");
}
// try-with-resources(自动关闭资源)
try (FileInputStream fis = new FileInputStream("file.txt")) {
// 使用fis
} catch (IOException e) {
e.printStackTrace();
}
6.3 抛出异常
// throws声明异常
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path);
}
// throw主动抛出异常
public void checkAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
}
// 自定义异常
public class BusinessException extends RuntimeException {
public BusinessException(String message) {
super(message);
}
}
6.4 常用异常方法
| 方法 |
说明 |
e.getMessage() |
获取异常信息 |
e.toString() |
获取异常类型和信息 |
e.printStackTrace() |
打印堆栈跟踪 |
七、常用类
7.1 Object类
所有类的父类,常用方法:
| 方法 |
说明 |
toString() |
返回对象字符串表示 |
equals(Object obj) |
比较对象相等 |
hashCode() |
返回哈希码 |
getClass() |
获取类对象 |
clone() |
创建对象副本 |
finalize() |
垃圾回收前调用 |
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
7.2 String类
// 创建字符串
String s1 = "Hello"; // 字符串常量池
String s2 = new String("Hello"); // 堆内存
// 常用方法
String str = " Hello World ";
str.length(); // 13
str.trim(); // "Hello World"
str.substring(2, 7); // "Hello"
str.indexOf("World"); // 8
str.contains("Hello"); // true
str.startsWith("He"); // true
str.endsWith("ld"); // true
str.replace("World", "Java"); // "Hello Java"
str.split(" "); // ["Hello", "World"]
str.toUpperCase(); // "HELLO WORLD"
str.toLowerCase(); // "hello world"
str.charAt(0); // 'H'
str.isEmpty(); // false
// StringBuilder(可变,线程不安全,效率高)
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString(); // "Hello World"
// StringBuffer(可变,线程安全,效率低)
StringBuffer sbf = new StringBuffer();
sbf.append("Hello");
7.3 包装类
| 基本类型 |
包装类 |
| byte |
Byte |
| short |
Short |
| int |
Integer |
| long |
Long |
| float |
Float |
| double |
Double |
| char |
Character |
| boolean |
Boolean |
// 装箱(基本类型 → 包装类)
Integer num1 = Integer.valueOf(10); // 手动装箱
Integer num2 = 10; // 自动装箱
// 拆箱(包装类 → 基本类型)
int n1 = num1.intValue(); // 手动拆箱
int n2 = num2; // 自动拆箱
// 字符串与数字转换
int num = Integer.parseInt("123"); // 123
String str = String.valueOf(123); // "123"
String str2 = Integer.toString(123); // "123"
7.4 Math类
Math.abs(-10); // 10(绝对值)
Math.max(10, 20); // 20(最大值)
Math.min(10, 20); // 10(最小值)
Math.pow(2, 3); // 8.0(幂运算)
Math.sqrt(16); // 4.0(平方根)
Math.round(3.5); // 4(四舍五入)
Math.ceil(3.2); // 4.0(向上取整)
Math.floor(3.8); // 3.0(向下取整)
Math.random(); // 0.0 ~ 1.0随机数
7.5 日期时间类
// Date(旧)
Date date = new Date();
System.out.println(date); // 当前时间
// SimpleDateFormat(旧)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(date); // 格式化
Date parseDate = sdf.parse("2024-01-01"); // 解析
// LocalDateTime(Java 8+,推荐)
LocalDateTime now = LocalDateTime.now();
LocalDate date = LocalDate.of(2024, 1, 1);
LocalTime time = LocalTime.of(12, 30, 0);
// 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String str = now.format(formatter);
// 时间计算
LocalDateTime tomorrow = now.plusDays(1);
LocalDateTime lastMonth = now.minusMonths(1);
// 获取时间戳
long timestamp = System.currentTimeMillis();
7.6 Random类
Random random = new Random();
random.nextInt(); // 随机整数
random.nextInt(100); // 0 ~ 99随机数
random.nextDouble(); // 0.0 ~ 1.0随机小数
random.nextBoolean(); // 随机布尔值
// 生成指定范围随机数 [min, max]
int num = random.nextInt(max - min + 1) + min;
八、集合框架
8.1 集合体系
Collection Map
│ │
├── List(有序,可重复) ├── HashMap(无序)
│ ├── ArrayList ├── LinkedHashMap(有序)
│ ├── LinkedList └── TreeMap(排序)
│ └── Vector
│
├── Set(无序,不可重复)
│ ├── HashSet
│ ├── LinkedHashSet
│ └── TreeSet
│
└── Queue(队列)
├── LinkedList
└── PriorityQueue
8.2 List接口
// ArrayList(基于数组,查询快,增删慢)
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add(1, "Orange"); // 指定位置插入
list.get(0); // 获取元素
list.remove(1); // 删除元素
list.size(); // 获取大小
list.contains("Apple"); // 是否包含
list.indexOf("Apple"); // 获取索引
list.clear(); // 清空
// LinkedList(基于链表,增删快,查询慢)
LinkedList<String> linkedList = new LinkedList<>();
linkedList.addFirst("First");
linkedList.addLast("Last");
linkedList.getFirst();
linkedList.getLast();
linkedList.removeFirst();
linkedList.removeLast();
// 遍历方式
// 1. for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 2. 增强for
for (String item : list) {
System.out.println(item);
}
// 3. 迭代器
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
// 4. forEach(Java 8+)
list.forEach(System.out::println);
8.3 Set接口
// HashSet(基于HashMap,无序)
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Apple"); // 重复,不会添加
System.out.println(set); // [Banana, Apple](无序)
// LinkedHashSet(保持插入顺序)
Set<String> linkedSet = new LinkedHashSet<>();
// TreeSet(自动排序)
Set<Integer> treeSet = new TreeSet<>();
treeSet.add(3);
treeSet.add(1);
treeSet.add(2);
System.out.println(treeSet); // [1, 2, 3]
8.4 Map接口
// HashMap(基于哈希表,无序)
Map<String, Integer> map = new HashMap<>();
map.put("Alice", 20);
map.put("Bob", 25);
map.put("Alice", 21); // 覆盖原有值
map.get("Alice"); // 21
map.containsKey("Bob"); // true
map.containsValue(25); // true
map.remove("Bob");
map.size();
map.isEmpty();
// 遍历Map
// 1. 遍历键
for (String key : map.keySet()) {
System.out.println(key + " = " + map.get(key));
}
// 2. 遍历键值对
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
// 3. forEach(Java 8+)
map.forEach((k, v) -> System.out.println(k + " = " + v));
// LinkedHashMap(保持插入顺序)
Map<String, Integer> linkedMap = new LinkedHashMap<>();
// TreeMap(按键排序)
Map<String, Integer> treeMap = new TreeMap<>();
8.5 Collections工具类
List<Integer> list = new ArrayList<>();
list.add(3);
list.add(1);
list.add(2);
// 排序
Collections.sort(list); // [1, 2, 3]
// 反转
Collections.reverse(list); // [3, 2, 1]
// 洗牌
Collections.shuffle(list);
// 查找最大值/最小值
Collections.max(list);
Collections.min(list);
// 二分查找(必须先排序)
Collections.binarySearch(list, 2);
// 替换所有元素
Collections.replaceAll(list, 1, 10);
// 线程安全集合
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
8.6 集合选择指南
| 场景 |
推荐集合 |
| 频繁查询,少增删 |
ArrayList |
| 频繁增删,少查询 |
LinkedList |
| 去重,无序 |
HashSet |
| 去重,保持顺序 |
LinkedHashSet |
| 去重,自动排序 |
TreeSet |
| 键值对,无序 |
HashMap |
| 键值对,保持顺序 |
LinkedHashMap |
| 键值对,按键排序 |
TreeMap |
九、泛型
9.1 泛型基础
// 泛型类
public class Box<T> {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
// 使用
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
String content = stringBox.getContent();
Box<Integer> intBox = new Box<>();
intBox.setContent(100);
9.2 泛型方法
public class GenericMethod {
// 泛型方法
public <T> void printArray(T[] array) {
for (T item : array) {
System.out.println(item);
}
}
// 泛型方法带返回值
public <T> T getFirst(T[] array) {
return array[0];
}
}
9.3 泛型约束
// 上界限定:只能是Number或其子类
public void printNumber(List<? extends Number> list) {
for (Number n : list) {
System.out.println(n);
}
}
// 下界限定:只能是Integer或其父类
public void addInteger(List<? super Integer> list) {
list.add(100);
}
// 泛型类约束
public class NumberBox<T extends Number> {
private T number;
}
9.4 通配符
| 通配符 |
说明 |
? |
任意类型 |
? extends T |
T或T的子类(上界) |
? super T |
T或T的父类(下界) |
十、IO流
10.1 IO流分类
IO流
├── 按流向
│ ├── 输入流(InputStream/Reader)
│ └── 输出流(OutputStream/Writer)
│
├── 按数据类型
│ ├── 字节流(InputStream/OutputStream)
│ └── 字符流(Reader/Writer)
│
└── 按功能
├── 节点流(直接操作数据源)
└── 处理流(包装节点流)
10.2 字节流
// 文件复制(字节流)
try (FileInputStream fis = new FileInputStream("source.txt");
FileOutputStream fos = new FileOutputStream("dest.txt")) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
10.3 字符流
// 文件复制(字符流)
try (FileReader fr = new FileReader("source.txt");
FileWriter fw = new FileWriter("dest.txt")) {
char[] buffer = new char[1024];
int len;
while ((len = fr.read(buffer)) != -1) {
fw.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
10.4 缓冲流
// 带缓冲的文件复制
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("source.txt"));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("dest.txt"))) {
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
10.5 转换流
// 字节流 → 字符流(指定编码)
try (InputStreamReader isr = new InputStreamReader(
new FileInputStream("file.txt"), "UTF-8");
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
10.6 序列化与反序列化
// 实现Serializable接口
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
// transient修饰的字段不会被序列化
private transient String password;
}
// 序列化(对象 → 文件)
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("student.dat"))) {
Student stu = new Student("张三", 20);
oos.writeObject(stu);
} catch (IOException e) {
e.printStackTrace();
}
// 反序列化(文件 → 对象)
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("student.dat"))) {
Student stu = (Student) ois.readObject();
System.out.println(stu.getName());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
10.7 常用IO流总结
| 流 |
说明 |
FileInputStream/FileOutputStream |
文件字节流 |
FileReader/FileWriter |
文件字符流 |
BufferedInputStream/BufferedOutputStream |
字节缓冲流 |
BufferedReader/BufferedWriter |
字符缓冲流 |
InputStreamReader/OutputStreamWriter |
转换流 |
ObjectInputStream/ObjectOutputStream |
对象流 |
ByteArrayInputStream/ByteArrayOutputStream |
字节数组流 |
PrintStream/PrintWriter |
打印流 |
十一、多线程
11.1 创建线程
// 方式1:继承Thread类
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程运行:" + Thread.currentThread().getName());
}
}
MyThread t1 = new MyThread();
t1.start();
// 方式2:实现Runnable接口(推荐)
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程运行:" + Thread.currentThread().getName());
}
}
Thread t2 = new Thread(new MyRunnable());
t2.start();
// 方式3:实现Callable接口(有返回值)
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "任务完成";
}
}
FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
new Thread(futureTask).start();
String result = futureTask.get(); // 阻塞获取结果
// 方式4:线程池(推荐)
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(() -> System.out.println("线程池任务"));
executor.shutdown();
11.2 线程状态
新建(New) → 就绪(Runnable) → 运行(Running) → 阻塞(Blocked) → 终止(Terminated)
| 状态 |
说明 |
| NEW |
新建,未启动 |
| RUNNABLE |
就绪或运行中 |
| BLOCKED |
等待锁 |
| WAITING |
无限等待(wait/join) |
| TIMED_WAITING |
限时等待(sleep/wait(timeout)) |
| TERMINATED |
执行完毕 |
11.3 线程方法
| 方法 |
说明 |
start() |
启动线程 |
run() |
线程执行体 |
sleep(ms) |
休眠指定毫秒 |
yield() |
让出CPU |
join() |
等待该线程执行完毕 |
interrupt() |
中断线程 |
isAlive() |
是否存活 |
setDaemon(true) |
设置为守护线程 |
11.4 线程同步
public class Counter {
private int count = 0;
// 方式1:synchronized方法
public synchronized void increment() {
count++;
}
// 方式2:synchronized代码块
public void decrement() {
synchronized (this) {
count--;
}
}
}
// 方式3:ReentrantLock(更灵活)
public class Counter2 {
private int count = 0;
private final Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
11.5 线程间通信
public class Buffer {
private int data;
private boolean empty = true;
// 生产者
public synchronized void produce(int value) throws InterruptedException {
while (!empty) {
wait(); // 等待消费
}
data = value;
empty = false;
notifyAll(); // 通知消费
}
// 消费者
public synchronized int consume() throws InterruptedException {
while (empty) {
wait(); // 等待生产
}
empty = true;
notifyAll(); // 通知生产
return data;
}
}
11.6 线程池
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
// 提交任务
executor.execute(() -> System.out.println("任务1"));
Future<Integer> future = executor.submit(() -> 42);
// 关闭线程池
executor.shutdown();
// 推荐方式(ThreadPoolExecutor)
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
60L, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new LinkedBlockingQueue<>(100) // 任务队列
);
11.7 线程池类型
| 线程池 |
说明 |
newFixedThreadPool(n) |
固定大小线程池 |
newCachedThreadPool() |
可缓存线程池 |
newSingleThreadExecutor() |
单线程线程池 |
newScheduledThreadPool(n) |
定时任务线程池 |
十二、网络编程
12.1 InetAddress
// 获取本机地址
InetAddress local = InetAddress.getLocalHost();
System.out.println(local.getHostName()); // 主机名
System.out.println(local.getHostAddress()); // IP地址
// 根据域名获取
InetAddress baidu = InetAddress.getByName("www.baidu.com");
System.out.println(baidu.getHostAddress());
12.2 TCP编程
// 服务端
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端启动...");
Socket socket = serverSocket.accept();
System.out.println("客户端连接:" + socket.getInetAddress());
// 接收数据
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String msg = reader.readLine();
System.out.println("收到:" + msg);
// 发送数据
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println("收到消息");
writer.flush();
socket.close();
serverSocket.close();
}
}
// 客户端
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8888);
// 发送数据
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println("Hello Server");
writer.flush();
// 接收数据
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String msg = reader.readLine();
System.out.println("收到:" + msg);
socket.close();
}
}
12.3 UDP编程
// 发送端
public class Sender {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket();
String msg = "Hello UDP";
byte[] data = msg.getBytes();
DatagramPacket packet = new DatagramPacket(
data, data.length,
InetAddress.getByName("localhost"), 9999);
socket.send(packet);
socket.close();
}
}
// 接收端
public class Receiver {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(9999);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String msg = new String(packet.getData(), 0, packet.getLength());
System.out.println("收到:" + msg);
socket.close();
}
}
十三、反射机制
13.1 获取Class对象
// 方式1:类名.class
Class<?> clazz1 = String.class;
// 方式2:对象.getClass()
String str = "Hello";
Class<?> clazz2 = str.getClass();
// 方式3:Class.forName()
Class<?> clazz3 = Class.forName("java.lang.String");
13.2 反射操作
public class Person {
private String name;
public int age;
public Person() {}
public Person(String name) { this.name = name; }
private void privateMethod() {}
public void publicMethod() {}
}
// 创建对象
Class<Person> clazz = Person.class;
Person person = clazz.newInstance(); // 调用无参构造
Constructor<Person> constructor = clazz.getConstructor(String.class);
Person person2 = constructor.newInstance("张三");
// 获取方法
Method[] methods = clazz.getMethods(); // 所有公共方法
Method[] declaredMethods = clazz.getDeclaredMethods(); // 所有声明的方法
Method method = clazz.getMethod("publicMethod");
method.invoke(person);
// 获取字段
Field[] fields = clazz.getFields(); // 所有公共字段
Field[] declaredFields = clazz.getDeclaredFields(); // 所有声明的字段
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true); // 访问私有字段
nameField.set(person, "李四");
String name = (String) nameField.get(person);
13.3 反射应用
// 动态代理
interface Hello {
void sayHello();
}
class HelloImpl implements Hello {
public void sayHello() {
System.out.println("Hello");
}
}
// 创建代理
Hello proxy = (Hello) Proxy.newProxyInstance(
Hello.class.getClassLoader(),
new Class[]{Hello.class},
(obj, method, args) -> {
System.out.println("前置处理");
Object result = method.invoke(new HelloImpl(), args);
System.out.println("后置处理");
return result;
}
);
proxy.sayHello();
十四、注解
14.1 内置注解
| 注解 |
说明 |
@Override |
重写父类方法 |
@Deprecated |
标记过时方法 |
@SuppressWarnings |
抑制警告 |
@FunctionalInterface |
函数式接口 |
14.2 元注解
| 注解 |
说明 |
@Target |
注解作用目标 |
@Retention |
注解保留策略 |
@Documented |
包含在JavaDoc中 |
@Inherited |
可被子类继承 |
14.3 自定义注解
// 定义注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {
String value() default "";
int count() default 0;
}
// 使用注解
@MyAnnotation(value = "test", count = 5)
public class MyClass {
@MyAnnotation("method")
public void myMethod() {}
}
// 读取注解
Class<MyClass> clazz = MyClass.class;
MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
System.out.println(annotation.value()); // test
System.out.println(annotation.count()); // 5
十五、Lambda表达式与Stream API
15.1 Lambda表达式
// 函数式接口
@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
}
// 传统匿名内部类
Calculator calc1 = new Calculator() {
@Override
public int calculate(int a, int b) {
return a + b;
}
};
// Lambda表达式
Calculator calc2 = (a, b) -> a + b;
// 常用函数式接口
// Predicate<T>:断言
Predicate<Integer> isEven = n -> n % 2 == 0;
boolean result = isEven.test(4); // true
// Consumer<T>:消费
Consumer<String> printer = s -> System.out.println(s);
printer.accept("Hello");
// Function<T, R>:转换
Function<String, Integer> length = s -> s.length();
int len = length.apply("Hello"); // 5
// Supplier<T>:供应
Supplier<Double> random = () -> Math.random();
double r = random.get();
15.2 Stream API
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 过滤
List<Integer> even = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList()); // [2, 4, 6, 8, 10]
// 映射
List<Integer> squares = numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList()); // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
// 排序
List<Integer> sorted = numbers.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList()); // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
// 去重
List<Integer> distinct = Arrays.asList(1, 2, 2, 3, 3, 3).stream()
.distinct()
.collect(Collectors.toList()); // [1, 2, 3]
// 限制和跳过
List<Integer> limited = numbers.stream()
.skip(3)
.limit(5)
.collect(Collectors.toList()); // [4, 5, 6, 7, 8]
// 聚合
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
int max = numbers.stream().mapToInt(Integer::intValue).max().orElse(0);
double avg = numbers.stream().mapToInt(Integer::intValue).average().orElse(0);
long count = numbers.stream().count();
// 匹配
boolean allEven = numbers.stream().allMatch(n -> n % 2 == 0);
boolean anyEven = numbers.stream().anyMatch(n -> n % 2 == 0);
boolean noneNegative = numbers.stream().noneMatch(n -> n < 0);
// 分组
Map<String, List<Integer>> groups = numbers.stream()
.collect(Collectors.groupingBy(n -> n % 2 == 0 ? "偶数" : "奇数"));
// 连接字符串
String joined = numbers.stream()
.map(String::valueOf)
.collect(Collectors.joining(", ")); // "1, 2, 3, 4, 5, 6, 7, 8, 9, 10"
// 并行流
List<Integer> parallelResult = numbers.parallelStream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
15.3 方法引用
// 静态方法引用
List<Integer> lengths = strings.stream()
.map(String::length)
.collect(Collectors.toList());
// 实例方法引用
strings.forEach(System.out::println);
// 对象方法引用
List<String> sorted = strings.stream()
.sorted(String::compareTo)
.collect(Collectors.toList());
// 构造方法引用
List<String> list = Stream.of("a", "b", "c")
.collect(Collectors.toList());
Set<String> set = Stream.of("a", "b", "c")
.collect(Collectors.toCollection(HashSet::new));
附录:常用快捷键(IDEA)
| 快捷键 |
功能 |
Ctrl + Shift + N |
查找文件 |
Ctrl + N |
查找类 |
Ctrl + Alt + L |
格式化代码 |
Ctrl + Shift + F |
全局搜索 |
Ctrl + D |
复制当前行 |
Ctrl + Y |
删除当前行 |
Alt + Enter |
快速修复 |
Ctrl + Shift + A |
查找操作 |
Ctrl + / |
单行注释 |
Ctrl + Shift + / |
多行注释 |
psvm |
生成main方法 |
sout |
生成System.out.println |
fori |
生成for循环 |
iter |
生成增强for循环 |
总结
本文档涵盖了Java SE的核心知识点,包括:
- 基础语法:数据类型、运算符、流程控制
- 面向对象:封装、继承、多态、抽象类、接口
- 常用类:String、包装类、日期时间
- 集合框架:List、Set、Map及其应用
- IO流:字节流、字符流、序列化
- 多线程:线程创建、同步、线程池
- 网络编程:TCP/UDP
- 高级特性:反射、注解、Lambda、Stream API
建议结合实践项目,加深对知识点的理解和应用。