JavaSE学习笔记

Java SE 学习笔记

本文档基于狂神说Java整理完善,涵盖Java SE核心知识点


目录

  1. Java基础
  2. Java语法基础
  3. 流程控制
  4. 数组
  5. 面向对象编程
  6. 异常处理
  7. 常用类
  8. 集合框架
  9. 泛型
  10. IO流
  11. 多线程
  12. 网络编程
  13. 反射机制
  14. 注解
  15. 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());  // 喂猫

多态前提

  1. 有继承关系
  2. 有方法重写
  3. 父类引用指向子类对象

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的核心知识点,包括:

  1. 基础语法:数据类型、运算符、流程控制
  2. 面向对象:封装、继承、多态、抽象类、接口
  3. 常用类:String、包装类、日期时间
  4. 集合框架:List、Set、Map及其应用
  5. IO流:字节流、字符流、序列化
  6. 多线程:线程创建、同步、线程池
  7. 网络编程:TCP/UDP
  8. 高级特性:反射、注解、Lambda、Stream API

建议结合实践项目,加深对知识点的理解和应用。

posted @ 2026-03-29 12:15  Exungsh💫  阅读(69)  评论(0)    收藏  举报