Skip to content

Java 特殊特性详解

概述

本文档详细介绍 Java 语言中的高级特性和核心概念,包括反射、枚举、类与对象、接口、注解、泛型、内部类等内容。这些特性是 Java 面向对象编程的核心,也是理解 Java 框架和高级编程技巧的基础。

目录

  1. 类与对象
  2. 接口
  3. 枚举
  4. 反射
  5. 注解
  6. 泛型
  7. 内部类
  8. Lambda 表达式
  9. 函数式接口
  10. Stream API

1. 类与对象

1.1 类的定义与结构

java
// 基本类定义
public class Person {
    // 成员变量(字段)
    private String name;
    private int age;
    private static int count = 0; // 静态变量
    
    // 静态代码块
    static {
        System.out.println("Person 类被加载");
    }
    
    // 实例代码块
    {
        count++;
        System.out.println("创建 Person 实例");
    }
    
    // 构造方法
    public Person() {
        this("Unknown", 0);
    }
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 实例方法
    public void introduce() {
        System.out.println("我是 " + name + ",今年 " + age + " 岁");
    }
    
    // 静态方法
    public static int getCount() {
        return count;
    }
    
    // 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) { this.age = age; }
}

1.2 继承与多态

java
// 父类
public abstract class Animal {
    protected String name;
    
    public Animal(String name) {
        this.name = name;
    }
    
    // 抽象方法
    public abstract void makeSound();
    
    // 具体方法
    public void sleep() {
        System.out.println(name + " 正在睡觉");
    }
    
    // final 方法,不能被重写
    public final void breathe() {
        System.out.println(name + " 正在呼吸");
    }
}

// 子类
public class Dog extends Animal {
    private String breed;
    
    public Dog(String name, String breed) {
        super(name); // 调用父类构造方法
        this.breed = breed;
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " 汪汪叫");
    }
    
    // 方法重载
    public void play() {
        System.out.println(name + " 在玩耍");
    }
    
    public void play(String toy) {
        System.out.println(name + " 在玩 " + toy);
    }
}

// 使用示例
public class InheritanceDemo {
    public static void main(String[] args) {
        Animal dog = new Dog("旺财", "金毛");
        dog.makeSound(); // 多态调用
        dog.sleep();
        dog.breathe();
        
        // 类型转换
        if (dog instanceof Dog) {
            Dog realDog = (Dog) dog;
            realDog.play();
            realDog.play("球");
        }
    }
}

1.3 访问修饰符

java
public class AccessModifierDemo {
    public String publicField = "公共字段";        // 任何地方都可访问
    protected String protectedField = "受保护字段"; // 同包或子类可访问
    String packageField = "包字段";               // 同包可访问
    private String privateField = "私有字段";      // 仅本类可访问
    
    public void demonstrateAccess() {
        System.out.println(publicField);
        System.out.println(protectedField);
        System.out.println(packageField);
        System.out.println(privateField); // 只有在本类中才能访问
    }
}

2. 接口

2.1 接口定义与实现

java
// 基本接口
public interface Drawable {
    // 常量(默认 public static final)
    String DEFAULT_COLOR = "黑色";
    
    // 抽象方法(默认 public abstract)
    void draw();
    void setColor(String color);
}

// 扩展接口
public interface Colorable extends Drawable {
    void changeColor(String newColor);
}

// 接口实现
public class Circle implements Colorable {
    private String color = DEFAULT_COLOR;
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制一个半径为 " + radius + " 的 " + color + " 圆形");
    }
    
    @Override
    public void setColor(String color) {
        this.color = color;
    }
    
    @Override
    public void changeColor(String newColor) {
        System.out.println("将颜色从 " + color + " 改为 " + newColor);
        this.color = newColor;
    }
}

2.2 默认方法和静态方法(Java 8+)

java
public interface ModernInterface {
    // 抽象方法
    void abstractMethod();
    
    // 默认方法
    default void defaultMethod() {
        System.out.println("这是默认方法");
        privateHelper();
    }
    
    // 静态方法
    static void staticMethod() {
        System.out.println("这是静态方法");
    }
    
    // 私有方法(Java 9+)
    private void privateHelper() {
        System.out.println("私有辅助方法");
    }
}

public class ModernClass implements ModernInterface {
    @Override
    public void abstractMethod() {
        System.out.println("实现抽象方法");
    }
    
    // 可以选择重写默认方法
    @Override
    public void defaultMethod() {
        System.out.println("重写的默认方法");
        ModernInterface.super.defaultMethod(); // 调用接口的默认方法
    }
}

2.3 函数式接口

java
@FunctionalInterface
public interface Calculator {
    int calculate(int a, int b);
    
    // 可以有默认方法
    default void printResult(int a, int b) {
        System.out.println("结果: " + calculate(a, b));
    }
}

// 使用示例
public class FunctionalInterfaceDemo {
    public static void main(String[] args) {
        // Lambda 表达式实现
        Calculator add = (a, b) -> a + b;
        Calculator multiply = (a, b) -> a * b;
        
        System.out.println("加法: " + add.calculate(5, 3));
        System.out.println("乘法: " + multiply.calculate(5, 3));
        
        add.printResult(5, 3);
    }
}

3. 枚举

3.1 基本枚举

java
// 简单枚举
public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

// 使用枚举
public class EnumBasicDemo {
    public static void main(String[] args) {
        Day today = Day.MONDAY;
        
        // 枚举比较
        if (today == Day.MONDAY) {
            System.out.println("今天是周一");
        }
        
        // switch 语句
        switch (today) {
            case MONDAY:
                System.out.println("周一,新的开始");
                break;
            case FRIDAY:
                System.out.println("周五,快到周末了");
                break;
            default:
                System.out.println("普通的一天");
        }
        
        // 枚举方法
        System.out.println("枚举名称: " + today.name());
        System.out.println("枚举序号: " + today.ordinal());
        
        // 遍历所有枚举值
        for (Day day : Day.values()) {
            System.out.println(day);
        }
    }
}

3.2 复杂枚举

java
public enum Planet {
    MERCURY(3.303e+23, 2.4397e6),
    VENUS(4.869e+24, 6.0518e6),
    EARTH(5.976e+24, 6.37814e6),
    MARS(6.421e+23, 3.3972e6);
    
    private final double mass;   // 质量(千克)
    private final double radius; // 半径(米)
    
    // 枚举构造方法
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    
    // 枚举方法
    public double getMass() { return mass; }
    public double getRadius() { return radius; }
    
    // 计算表面重力
    public double surfaceGravity() {
        final double G = 6.67300E-11;
        return G * mass / (radius * radius);
    }
    
    // 计算在该星球上的重量
    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
}

// 使用复杂枚举
public class PlanetDemo {
    public static void main(String[] args) {
        double earthWeight = 75.0; // 地球上的重量
        
        for (Planet planet : Planet.values()) {
            double weight = planet.surfaceWeight(earthWeight);
            System.out.printf("在 %s 上的重量: %.2f kg%n", 
                            planet.name(), weight);
        }
    }
}

3.3 枚举实现接口

java
public interface Operation {
    double apply(double x, double y);
}

public enum BasicOperation implements Operation {
    PLUS("+") {
        @Override
        public double apply(double x, double y) { return x + y; }
    },
    MINUS("-") {
        @Override
        public double apply(double x, double y) { return x - y; }
    },
    TIMES("*") {
        @Override
        public double apply(double x, double y) { return x * y; }
    },
    DIVIDE("/") {
        @Override
        public double apply(double x, double y) { return x / y; }
    };
    
    private final String symbol;
    
    BasicOperation(String symbol) {
        this.symbol = symbol;
    }
    
    @Override
    public String toString() {
        return symbol;
    }
}

// 使用示例
public class OperationDemo {
    public static void main(String[] args) {
        double x = 10.0, y = 3.0;
        
        for (BasicOperation op : BasicOperation.values()) {
            System.out.printf("%.1f %s %.1f = %.2f%n", 
                            x, op, y, op.apply(x, y));
        }
    }
}

4. 反射

4.1 Class 对象

java
import java.lang.reflect.*;

public class ReflectionBasics {
    public static void main(String[] args) throws Exception {
        // 获取 Class 对象的三种方式
        Class<?> clazz1 = String.class;
        Class<?> clazz2 = "Hello".getClass();
        Class<?> clazz3 = Class.forName("java.lang.String");
        
        System.out.println("类名: " + clazz1.getName());
        System.out.println("简单类名: " + clazz1.getSimpleName());
        System.out.println("包名: " + clazz1.getPackage().getName());
        System.out.println("是否为接口: " + clazz1.isInterface());
        System.out.println("是否为数组: " + clazz1.isArray());
        System.out.println("父类: " + clazz1.getSuperclass());
        
        // 获取实现的接口
        Class<?>[] interfaces = clazz1.getInterfaces();
        System.out.println("实现的接口:");
        for (Class<?> intf : interfaces) {
            System.out.println("  " + intf.getName());
        }
    }
}

4.2 反射操作字段

java
import java.lang.reflect.Field;

public class Student {
    private String name;
    public int age;
    protected String grade;
    static String school = "清华大学";
    
    public Student(String name, int age, String grade) {
        this.name = name;
        this.age = age;
        this.grade = grade;
    }
    
    @Override
    public String toString() {
        return String.format("Student{name='%s', age=%d, grade='%s'}", 
                           name, age, grade);
    }
}

public class FieldReflectionDemo {
    public static void main(String[] args) throws Exception {
        Student student = new Student("张三", 20, "大二");
        Class<?> clazz = student.getClass();
        
        System.out.println("=== 获取所有字段 ===");
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.printf("字段: %s, 类型: %s, 修饰符: %s%n",
                            field.getName(), 
                            field.getType().getSimpleName(),
                            Modifier.toString(field.getModifiers()));
        }
        
        System.out.println("\n=== 操作私有字段 ===");
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true); // 设置可访问私有字段
        
        String originalName = (String) nameField.get(student);
        System.out.println("原始姓名: " + originalName);
        
        nameField.set(student, "李四");
        System.out.println("修改后: " + student);
        
        System.out.println("\n=== 操作静态字段 ===");
        Field schoolField = clazz.getDeclaredField("school");
        System.out.println("学校: " + schoolField.get(null)); // 静态字段传入 null
    }
}

4.3 反射操作方法

java
import java.lang.reflect.Method;

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    
    private String formatResult(String operation, int result) {
        return String.format("%s 的结果是: %d", operation, result);
    }
    
    public static void printInfo() {
        System.out.println("这是一个计算器类");
    }
    
    // 重载方法
    public double add(double a, double b) {
        return a + b;
    }
}

public class MethodReflectionDemo {
    public static void main(String[] args) throws Exception {
        Calculator calc = new Calculator();
        Class<?> clazz = calc.getClass();
        
        System.out.println("=== 获取所有方法 ===");
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.printf("方法: %s, 返回类型: %s, 参数: %s%n",
                            method.getName(),
                            method.getReturnType().getSimpleName(),
                            java.util.Arrays.toString(method.getParameterTypes()));
        }
        
        System.out.println("\n=== 调用公共方法 ===");
        Method addMethod = clazz.getMethod("add", int.class, int.class);
        int result = (int) addMethod.invoke(calc, 5, 3);
        System.out.println("5 + 3 = " + result);
        
        System.out.println("\n=== 调用私有方法 ===");
        Method formatMethod = clazz.getDeclaredMethod("formatResult", String.class, int.class);
        formatMethod.setAccessible(true);
        String formatted = (String) formatMethod.invoke(calc, "加法", result);
        System.out.println(formatted);
        
        System.out.println("\n=== 调用静态方法 ===");
        Method staticMethod = clazz.getMethod("printInfo");
        staticMethod.invoke(null); // 静态方法传入 null
    }
}

4.4 反射操作构造方法

java
import java.lang.reflect.Constructor;

public class Person {
    private String name;
    private int age;
    
    public Person() {
        this("Unknown", 0);
    }
    
    public Person(String name) {
        this(name, 0);
    }
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    private Person(int age) {
        this("Private", age);
    }
    
    @Override
    public String toString() {
        return String.format("Person{name='%s', age=%d}", name, age);
    }
}

public class ConstructorReflectionDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Person.class;
        
        System.out.println("=== 获取所有构造方法 ===");
        Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.printf("构造方法: %s, 参数: %s%n",
                            constructor.getName(),
                            java.util.Arrays.toString(constructor.getParameterTypes()));
        }
        
        System.out.println("\n=== 使用不同构造方法创建对象 ===");
        
        // 无参构造方法
        Constructor<?> defaultConstructor = clazz.getConstructor();
        Person person1 = (Person) defaultConstructor.newInstance();
        System.out.println("无参构造: " + person1);
        
        // 单参构造方法
        Constructor<?> nameConstructor = clazz.getConstructor(String.class);
        Person person2 = (Person) nameConstructor.newInstance("张三");
        System.out.println("单参构造: " + person2);
        
        // 双参构造方法
        Constructor<?> fullConstructor = clazz.getConstructor(String.class, int.class);
        Person person3 = (Person) fullConstructor.newInstance("李四", 25);
        System.out.println("双参构造: " + person3);
        
        // 私有构造方法
        Constructor<?> privateConstructor = clazz.getDeclaredConstructor(int.class);
        privateConstructor.setAccessible(true);
        Person person4 = (Person) privateConstructor.newInstance(30);
        System.out.println("私有构造: " + person4);
    }
}

4.5 反射工具类

java
import java.lang.reflect.*;
import java.util.*;

public class ReflectionUtils {
    
    /**
     * 获取对象的所有字段值
     */
    public static Map<String, Object> getFieldValues(Object obj) {
        Map<String, Object> fieldValues = new HashMap<>();
        Class<?> clazz = obj.getClass();
        
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object value = field.get(obj);
                fieldValues.put(field.getName(), value);
            } catch (IllegalAccessException e) {
                fieldValues.put(field.getName(), "无法访问");
            }
        }
        
        return fieldValues;
    }
    
    /**
     * 复制对象(浅拷贝)
     */
    public static <T> T copyObject(T source) throws Exception {
        Class<?> clazz = source.getClass();
        
        @SuppressWarnings("unchecked")
        T target = (T) clazz.getDeclaredConstructor().newInstance();
        
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            Object value = field.get(source);
            field.set(target, value);
        }
        
        return target;
    }
    
    /**
     * 调用对象的方法
     */
    public static Object invokeMethod(Object obj, String methodName, 
                                    Class<?>[] paramTypes, Object... args) 
                                    throws Exception {
        Class<?> clazz = obj.getClass();
        Method method = clazz.getDeclaredMethod(methodName, paramTypes);
        method.setAccessible(true);
        return method.invoke(obj, args);
    }
    
    /**
     * 打印类的详细信息
     */
    public static void printClassInfo(Class<?> clazz) {
        System.out.println("=== 类信息: " + clazz.getSimpleName() + " ===");
        
        // 字段信息
        System.out.println("\n字段:");
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.printf("  %s %s %s%n",
                            Modifier.toString(field.getModifiers()),
                            field.getType().getSimpleName(),
                            field.getName());
        }
        
        // 构造方法信息
        System.out.println("\n构造方法:");
        Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.printf("  %s %s(%s)%n",
                            Modifier.toString(constructor.getModifiers()),
                            constructor.getName(),
                            Arrays.toString(constructor.getParameterTypes()));
        }
        
        // 方法信息
        System.out.println("\n方法:");
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.printf("  %s %s %s(%s)%n",
                            Modifier.toString(method.getModifiers()),
                            method.getReturnType().getSimpleName(),
                            method.getName(),
                            Arrays.toString(method.getParameterTypes()));
        }
    }
}

// 使用示例
public class ReflectionUtilsDemo {
    public static void main(String[] args) throws Exception {
        Student student = new Student("王五", 22, "大三");
        
        // 获取字段值
        Map<String, Object> fieldValues = ReflectionUtils.getFieldValues(student);
        System.out.println("字段值: " + fieldValues);
        
        // 复制对象
        Student copy = ReflectionUtils.copyObject(student);
        System.out.println("复制的对象: " + copy);
        
        // 打印类信息
        ReflectionUtils.printClassInfo(Student.class);
    }
}

5. 注解

5.1 内置注解

java
// 使用内置注解
public class BuiltInAnnotationsDemo {
    
    @Deprecated
    public void oldMethod() {
        System.out.println("这是一个过时的方法");
    }
    
    @Override
    public String toString() {
        return "BuiltInAnnotationsDemo";
    }
    
    @SuppressWarnings("unchecked")
    public void suppressWarningsMethod() {
        @SuppressWarnings("rawtypes")
        List list = new ArrayList();
        list.add("item");
    }
    
    @SafeVarargs
    public final void safeVarargsMethod(List<String>... lists) {
        for (List<String> list : lists) {
            System.out.println(list);
        }
    }
}

5.2 自定义注解

java
import java.lang.annotation.*;

// 方法级注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Timer {
    String value() default "";
    boolean enabled() default true;
}

// 类级注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {
    String name() default "";
    String version() default "1.0";
}

// 字段级注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Inject {
    String value() default "";
    boolean required() default true;
}

// 参数级注解
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNull {
}

// 多目标注解
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Validate {
    String pattern() default "";
    int min() default 0;
    int max() default Integer.MAX_VALUE;
}

5.3 注解处理器

java
import java.lang.reflect.Method;
import java.lang.reflect.Field;

@Component(name = "UserService", version = "2.0")
public class UserService {
    
    @Inject("userRepository")
    private String repository;
    
    @Validate(min = 1, max = 100)
    private int userId;
    
    @Timer("getUserById")
    public String getUserById(@NotNull String id) {
        return "User: " + id;
    }
    
    @Timer(value = "getAllUsers", enabled = false)
    public void getAllUsers() {
        System.out.println("获取所有用户");
    }
}

// 注解处理器
public class AnnotationProcessor {
    
    public static void processClass(Class<?> clazz) {
        System.out.println("=== 处理类: " + clazz.getSimpleName() + " ===");
        
        // 处理类级注解
        if (clazz.isAnnotationPresent(Component.class)) {
            Component component = clazz.getAnnotation(Component.class);
            System.out.printf("组件名称: %s, 版本: %s%n", 
                            component.name(), component.version());
        }
        
        // 处理字段注解
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Inject.class)) {
                Inject inject = field.getAnnotation(Inject.class);
                System.out.printf("注入字段: %s, 值: %s, 必需: %s%n",
                                field.getName(), inject.value(), inject.required());
            }
            
            if (field.isAnnotationPresent(Validate.class)) {
                Validate validate = field.getAnnotation(Validate.class);
                System.out.printf("验证字段: %s, 最小值: %d, 最大值: %d%n",
                                field.getName(), validate.min(), validate.max());
            }
        }
        
        // 处理方法注解
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(Timer.class)) {
                Timer timer = method.getAnnotation(Timer.class);
                System.out.printf("计时方法: %s, 名称: %s, 启用: %s%n",
                                method.getName(), timer.value(), timer.enabled());
            }
        }
    }
    
    public static void main(String[] args) {
        processClass(UserService.class);
    }
}

5.4 注解驱动的简单框架

java
import java.lang.reflect.*;
import java.util.*;

// 简单的依赖注入容器
public class SimpleContainer {
    private Map<String, Object> beans = new HashMap<>();
    
    public void registerBean(String name, Object bean) {
        beans.put(name, bean);
    }
    
    public <T> T getBean(String name, Class<T> type) {
        return type.cast(beans.get(name));
    }
    
    public void injectDependencies(Object target) throws Exception {
        Class<?> clazz = target.getClass();
        Field[] fields = clazz.getDeclaredFields();
        
        for (Field field : fields) {
            if (field.isAnnotationPresent(Inject.class)) {
                Inject inject = field.getAnnotation(Inject.class);
                String beanName = inject.value().isEmpty() ? 
                                field.getName() : inject.value();
                
                Object dependency = beans.get(beanName);
                if (dependency != null) {
                    field.setAccessible(true);
                    field.set(target, dependency);
                    System.out.println("注入依赖: " + beanName + " -> " + field.getName());
                } else if (inject.required()) {
                    throw new RuntimeException("找不到必需的依赖: " + beanName);
                }
            }
        }
    }
    
    public Object executeWithTimer(Object target, String methodName, 
                                 Class<?>[] paramTypes, Object... args) 
                                 throws Exception {
        Method method = target.getClass().getDeclaredMethod(methodName, paramTypes);
        
        if (method.isAnnotationPresent(Timer.class)) {
            Timer timer = method.getAnnotation(Timer.class);
            if (timer.enabled()) {
                long startTime = System.nanoTime();
                Object result = method.invoke(target, args);
                long endTime = System.nanoTime();
                
                String timerName = timer.value().isEmpty() ? 
                                 methodName : timer.value();
                System.out.printf("方法 %s 执行时间: %.2f ms%n", 
                                timerName, (endTime - startTime) / 1_000_000.0);
                return result;
            }
        }
        
        return method.invoke(target, args);
    }
}

// 使用示例
public class FrameworkDemo {
    public static void main(String[] args) throws Exception {
        SimpleContainer container = new SimpleContainer();
        
        // 注册依赖
        container.registerBean("userRepository", "UserRepositoryImpl");
        
        // 创建服务并注入依赖
        UserService userService = new UserService();
        container.injectDependencies(userService);
        
        // 执行带计时的方法
        container.executeWithTimer(userService, "getUserById", 
                                 new Class[]{String.class}, "123");
        container.executeWithTimer(userService, "getAllUsers", new Class[]{});
    }
}

6. 泛型

6.1 泛型基础

java
// 泛型类
public class Box<T> {
    private T content;
    
    public Box(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=" + content + "}";
    }
}

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

// 实现泛型接口
public class Student implements Comparable<Student> {
    private String name;
    private int score;
    
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    
    @Override
    public int compareTo(Student other) {
        return Integer.compare(this.score, other.score);
    }
    
    // getters and toString...
    public String getName() { return name; }
    public int getScore() { return score; }
    
    @Override
    public String toString() {
        return String.format("Student{name='%s', score=%d}", name, score);
    }
}

// 使用泛型
public class GenericBasicsDemo {
    public static void main(String[] args) {
        // 泛型类使用
        Box<String> stringBox = new Box<>("Hello");
        Box<Integer> intBox = new Box<>(42);
        
        System.out.println(stringBox);
        System.out.println(intBox);
        
        // 泛型接口使用
        Student student1 = new Student("张三", 85);
        Student student2 = new Student("李四", 92);
        
        int result = student1.compareTo(student2);
        System.out.println("比较结果: " + result);
    }
}

6.2 泛型方法

java
import java.util.*;

public class GenericMethods {
    
    // 泛型方法
    public static <T> void swap(T[] array, int i, int j) {
        T temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    
    // 多个类型参数
    public static <T, U> void printPair(T first, U second) {
        System.out.println("第一个: " + first + ", 第二个: " + second);
    }
    
    // 有界类型参数
    public static <T extends Number> double sum(List<T> numbers) {
        double total = 0.0;
        for (T number : numbers) {
            total += number.doubleValue();
        }
        return total;
    }
    
    // 递归类型边界
    public static <T extends Comparable<T>> T max(List<T> list) {
        if (list.isEmpty()) {
            return null;
        }
        
        T max = list.get(0);
        for (T item : list) {
            if (item.compareTo(max) > 0) {
                max = item;
            }
        }
        return max;
    }
    
    public static void main(String[] args) {
        // 使用泛型方法
        String[] strings = {"a", "b", "c"};
        System.out.println("交换前: " + Arrays.toString(strings));
        swap(strings, 0, 2);
        System.out.println("交换后: " + Arrays.toString(strings));
        
        // 多个类型参数
        printPair("Hello", 42);
        printPair(3.14, true);
        
        // 有界类型参数
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
        List<Double> doubles = Arrays.asList(1.1, 2.2, 3.3);
        
        System.out.println("整数和: " + sum(integers));
        System.out.println("小数和: " + sum(doubles));
        
        // 递归类型边界
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        System.out.println("最大字符串: " + max(words));
    }
}

6.3 通配符

java
import java.util.*;

public class WildcardsDemo {
    
    // 上界通配符 (? extends T)
    public static double sumOfNumbers(List<? extends Number> numbers) {
        double sum = 0.0;
        for (Number number : numbers) {
            sum += number.doubleValue();
        }
        return sum;
    }
    
    // 下界通配符 (? super T)
    public static void addNumbers(List<? super Integer> numbers) {
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
    }
    
    // 无界通配符 (?)
    public static void printList(List<?> list) {
        for (Object item : list) {
            System.out.println(item);
        }
    }
    
    // PECS 原则示例 (Producer Extends, Consumer Super)
    public static <T> void copy(List<? extends T> source, List<? super T> destination) {
        for (T item : source) {
            destination.add(item);
        }
    }
    
    public static void main(String[] args) {
        // 上界通配符
        List<Integer> integers = Arrays.asList(1, 2, 3);
        List<Double> doubles = Arrays.asList(1.1, 2.2, 3.3);
        
        System.out.println("整数和: " + sumOfNumbers(integers));
        System.out.println("小数和: " + sumOfNumbers(doubles));
        
        // 下界通配符
        List<Number> numbers = new ArrayList<>();
        List<Object> objects = new ArrayList<>();
        
        addNumbers(numbers);
        addNumbers(objects);
        
        System.out.println("Numbers: " + numbers);
        System.out.println("Objects: " + objects);
        
        // 无界通配符
        printList(integers);
        printList(Arrays.asList("a", "b", "c"));
        
        // PECS 示例
        List<String> source = Arrays.asList("hello", "world");
        List<Object> destination = new ArrayList<>();
        copy(source, destination);
        System.out.println("复制结果: " + destination);
    }
}

6.4 类型擦除和限制

java
import java.lang.reflect.*;
import java.util.*;

public class TypeErasureDemo {
    
    public static void demonstrateTypeErasure() {
        List<String> stringList = new ArrayList<>();
        List<Integer> intList = new ArrayList<>();
        
        // 运行时类型相同
        System.out.println("String List 类型: " + stringList.getClass());
        System.out.println("Integer List 类型: " + intList.getClass());
        System.out.println("类型相同: " + (stringList.getClass() == intList.getClass()));
    }
    
    // 泛型数组的限制
    public static void genericArrayLimitations() {
        // 编译错误: 不能创建泛型数组
        // List<String>[] stringLists = new List<String>[10];
        
        // 可以这样做
        @SuppressWarnings("unchecked")
        List<String>[] stringLists = new List[10];
        stringLists[0] = new ArrayList<>();
        
        // 或者使用 ArrayList
        List<List<String>> listOfLists = new ArrayList<>();
    }
    
    // 获取泛型信息的方法
    public static void getGenericInfo() throws Exception {
        // 通过反射获取泛型信息
        Method method = TypeErasureDemo.class.getMethod("methodWithGenericParam", List.class);
        Type[] paramTypes = method.getGenericParameterTypes();
        
        for (Type paramType : paramTypes) {
            if (paramType instanceof ParameterizedType) {
                ParameterizedType pType = (ParameterizedType) paramType;
                System.out.println("参数化类型: " + pType);
                System.out.println("原始类型: " + pType.getRawType());
                System.out.println("类型参数: " + Arrays.toString(pType.getActualTypeArguments()));
            }
        }
    }
    
    public void methodWithGenericParam(List<String> list) {
        // 方法体
    }
    
    public static void main(String[] args) throws Exception {
        demonstrateTypeErasure();
        genericArrayLimitations();
        getGenericInfo();
    }
}

7. 内部类

7.1 成员内部类

java
public class OuterClass {
    private String outerField = "外部类字段";
    private static String staticField = "静态字段";
    
    // 成员内部类
    public class InnerClass {
        private String innerField = "内部类字段";
        
        public void innerMethod() {
            // 可以访问外部类的所有成员
            System.out.println("访问外部类字段: " + outerField);
            System.out.println("访问静态字段: " + staticField);
            System.out.println("内部类字段: " + innerField);
            
            // 调用外部类方法
            outerMethod();
        }
        
        public void accessOuterThis() {
            // 访问外部类的 this 引用
            System.out.println("外部类实例: " + OuterClass.this);
        }
    }
    
    public void outerMethod() {
        System.out.println("外部类方法");
        
        // 在外部类中创建内部类实例
        InnerClass inner = new InnerClass();
        inner.innerMethod();
    }
    
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        
        // 创建内部类实例的方式
        OuterClass.InnerClass inner1 = outer.new InnerClass();
        inner1.innerMethod();
        
        // 另一种方式
        OuterClass.InnerClass inner2 = new OuterClass().new InnerClass();
        inner2.accessOuterThis();
    }
}

7.2 静态内部类

java
public class StaticInnerDemo {
    private String instanceField = "实例字段";
    private static String staticField = "静态字段";
    
    // 静态内部类
    public static class StaticInner {
        private String innerField = "静态内部类字段";
        
        public void innerMethod() {
            // 只能访问外部类的静态成员
            System.out.println("访问静态字段: " + staticField);
            System.out.println("内部类字段: " + innerField);
            
            // 编译错误:不能访问实例字段
            // System.out.println(instanceField);
        }
        
        public static void staticInnerMethod() {
            System.out.println("静态内部类的静态方法");
        }
    }
    
    public static void main(String[] args) {
        // 创建静态内部类实例(不需要外部类实例)
        StaticInner staticInner = new StaticInner();
        staticInner.innerMethod();
        
        // 调用静态内部类的静态方法
        StaticInner.staticInnerMethod();
    }
}

7.3 局部内部类

java
public class LocalInnerDemo {
    private String outerField = "外部类字段";
    
    public void methodWithLocalInner() {
        final String localVar = "局部变量";
        String effectivelyFinalVar = "实际final变量";
        
        // 局部内部类
        class LocalInner {
            private String innerField = "局部内部类字段";
            
            public void innerMethod() {
                System.out.println("外部类字段: " + outerField);
                System.out.println("局部变量: " + localVar);
                System.out.println("实际final变量: " + effectivelyFinalVar);
                System.out.println("内部类字段: " + innerField);
            }
        }
        
        // 在方法内使用局部内部类
        LocalInner localInner = new LocalInner();
        localInner.innerMethod();
        
        // effectivelyFinalVar = "修改后"; // 编译错误:会破坏 effectively final
    }
    
    public static void main(String[] args) {
        LocalInnerDemo demo = new LocalInnerDemo();
        demo.methodWithLocalInner();
    }
}

7.4 匿名内部类

java
import java.util.*;

public class AnonymousInnerDemo {
    
    // 接口
    interface Greeting {
        void sayHello(String name);
    }
    
    // 抽象类
    abstract class Animal {
        protected String name;
        
        public Animal(String name) {
            this.name = name;
        }
        
        public abstract void makeSound();
        
        public void sleep() {
            System.out.println(name + " 正在睡觉");
        }
    }
    
    public void demonstrateAnonymousClasses() {
        // 实现接口的匿名类
        Greeting greeting = new Greeting() {
            @Override
            public void sayHello(String name) {
                System.out.println("你好, " + name + "!");
            }
        };
        greeting.sayHello("张三");
        
        // 继承抽象类的匿名类
        Animal dog = new Animal("旺财") {
            @Override
            public void makeSound() {
                System.out.println(name + " 汪汪叫");
            }
        };
        dog.makeSound();
        dog.sleep();
        
        // 继承具体类的匿名类
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("匿名线程正在运行");
            }
        };
        thread.start();
        
        // 在集合操作中使用匿名类
        List<String> names = Arrays.asList("张三", "李四", "王五");
        
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return s2.compareTo(s1); // 降序排列
            }
        });
        
        System.out.println("排序后: " + names);
    }
    
    public static void main(String[] args) {
        AnonymousInnerDemo demo = new AnonymousInnerDemo();
        demo.demonstrateAnonymousClasses();
    }
}

7.5 内部类的实际应用

java
import java.util.*;

// 迭代器模式的实现
public class MyList<T> {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_CAPACITY = 10;
    
    public MyList() {
        elements = new Object[DEFAULT_CAPACITY];
    }
    
    public void add(T element) {
        if (size >= elements.length) {
            resize();
        }
        elements[size++] = element;
    }
    
    @SuppressWarnings("unchecked")
    public T get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        return (T) elements[index];
    }
    
    public int size() {
        return size;
    }
    
    private void resize() {
        elements = Arrays.copyOf(elements, elements.length * 2);
    }
    
    // 成员内部类实现迭代器
    public class ListIterator implements Iterator<T> {
        private int currentIndex = 0;
        
        @Override
        public boolean hasNext() {
            return currentIndex < size;
        }
        
        @Override
        @SuppressWarnings("unchecked")
        public T next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            return (T) elements[currentIndex++];
        }
    }
    
    public Iterator<T> iterator() {
        return new ListIterator();
    }
    
    // 静态内部类实现构建器模式
    public static class Builder<T> {
        private MyList<T> list = new MyList<>();
        
        public Builder<T> add(T element) {
            list.add(element);
            return this;
        }
        
        public MyList<T> build() {
            return list;
        }
    }
    
    public static <T> Builder<T> builder() {
        return new Builder<>();
    }
    
    public static void main(String[] args) {
        // 使用构建器创建列表
        MyList<String> list = MyList.<String>builder()
            .add("Apple")
            .add("Banana")
            .add("Cherry")
            .build();
        
        // 使用迭代器遍历
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        
        // 增强for循环(需要实现Iterable接口)
        System.out.println("\n直接访问:");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}

8. Lambda 表达式

8.1 Lambda 基础语法

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

public class LambdaBasics {
    
    public static void main(String[] args) {
        // 基本语法形式
        
        // 1. 无参数
        Runnable r1 = () -> System.out.println("Hello Lambda");
        r1.run();
        
        // 2. 单个参数(可省略括号)
        Consumer<String> c1 = s -> System.out.println("消费: " + s);
        Consumer<String> c2 = (s) -> System.out.println("消费: " + s);
        c1.accept("测试");
        
        // 3. 多个参数
        BinaryOperator<Integer> add = (a, b) -> a + b;
        System.out.println("加法: " + add.apply(5, 3));
        
        // 4. 多行代码块
        BinaryOperator<Integer> complex = (a, b) -> {
            System.out.println("计算 " + a + " 和 " + b + " 的和");
            int result = a + b;
            return result;
        };
        System.out.println("复杂计算: " + complex.apply(10, 20));
        
        // 5. 类型推断
        List<String> list = Arrays.asList("apple", "banana", "cherry");
        list.forEach(item -> System.out.println(item)); // 推断 item 为 String
        
        // 6. 方法引用
        list.forEach(System.out::println); // 等价于上面的 lambda
    }
}

8.2 常用函数式接口

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

public class FunctionalInterfacesDemo {
    
    public static void main(String[] args) {
        // Predicate<T> - 断言型接口
        Predicate<Integer> isEven = n -> n % 2 == 0;
        Predicate<Integer> isPositive = n -> n > 0;
        
        System.out.println("4 是偶数且为正数: " + isEvenAndPositive.test(4));
        System.out.println("-2 是偶数且为正数: " + isEvenAndPositive.test(-2));
        
        // Function<T, R> - 函数型接口
        Function<String, Integer> stringLength = s -> s.length();
        Function<Integer, String> intToString = i -> "数字: " + i;
        
        System.out.println("字符串长度: " + stringLength.apply("Hello"));
        
        // 函数组合
        Function<String, String> lengthToString = stringLength.andThen(intToString);
        System.out.println(lengthToString.apply("Lambda"));
        
        // Consumer<T> - 消费型接口
        Consumer<String> printer = s -> System.out.println("打印: " + s);
        Consumer<String> logger = s -> System.out.println("日志: " + s);
        
        // 组合消费者
        Consumer<String> combined = printer.andThen(logger);
        combined.accept("测试消息");
        
        // Supplier<T> - 供给型接口
        Supplier<String> randomString = () -> "随机数: " + Math.random();
        Supplier<Date> currentTime = Date::new;
        
        System.out.println(randomString.get());
        System.out.println("当前时间: " + currentTime.get());
        
        // UnaryOperator<T> - 一元操作符
        UnaryOperator<String> toUpperCase = String::toUpperCase;
        UnaryOperator<Integer> square = x -> x * x;
        
        System.out.println("转大写: " + toUpperCase.apply("hello"));
        System.out.println("平方: " + square.apply(5));
        
        // BinaryOperator<T> - 二元操作符
        BinaryOperator<String> concat = (s1, s2) -> s1 + s2;
        BinaryOperator<Integer> max = Integer::max;
        
        System.out.println("连接: " + concat.apply("Hello", "World"));
        System.out.println("最大值: " + max.apply(10, 20));
    }
}

8.3 方法引用

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

public class MethodReferenceDemo {
    
    public static void staticMethod(String s) {
        System.out.println("静态方法: " + s);
    }
    
    public void instanceMethod(String s) {
        System.out.println("实例方法: " + s);
    }
    
    public static void main(String[] args) {
        List<String> list = Arrays.asList("apple", "banana", "cherry");
        
        // 1. 静态方法引用
        Consumer<String> staticRef = MethodReferenceDemo::staticMethod;
        list.forEach(staticRef);
        
        // 2. 实例方法引用
        MethodReferenceDemo demo = new MethodReferenceDemo();
        Consumer<String> instanceRef = demo::instanceMethod;
        list.forEach(instanceRef);
        
        // 3. 特定类型的任意对象的实例方法引用
        Function<String, Integer> lengthRef = String::length;
        list.stream().map(lengthRef).forEach(System.out::println);
        
        // 4. 构造方法引用
        Supplier<List<String>> listSupplier = ArrayList::new;
        Function<Integer, List<String>> listWithCapacity = ArrayList::new;
        
        List<String> newList1 = listSupplier.get();
        List<String> newList2 = listWithCapacity.apply(10);
        
        System.out.println("新列表1: " + newList1);
        System.out.println("新列表2容量: " + newList2.size());
        
        // 5. 数组构造方法引用
        Function<Integer, String[]> arrayCreator = String[]::new;
        String[] array = arrayCreator.apply(5);
        System.out.println("数组长度: " + array.length);
    }
}

8.4 Lambda 表达式的实际应用

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

public class LambdaApplications {
    
    static class Person {
        private String name;
        private int age;
        private String city;
        
        public Person(String name, int age, String city) {
            this.name = name;
            this.age = age;
            this.city = city;
        }
        
        // getters
        public String getName() { return name; }
        public int getAge() { return age; }
        public String getCity() { return city; }
        
        @Override
        public String toString() {
            return String.format("Person{name='%s', age=%d, city='%s'}", name, age, city);
        }
    }
    
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("张三", 25, "北京"),
            new Person("李四", 30, "上海"),
            new Person("王五", 22, "北京"),
            new Person("赵六", 35, "深圳"),
            new Person("钱七", 28, "上海")
        );
        
        // 1. 排序
        System.out.println("=== 按年龄排序 ===");
        people.stream()
              .sorted((p1, p2) -> Integer.compare(p1.getAge(), p2.getAge()))
              .forEach(System.out::println);
        
        // 使用 Comparator.comparing
        System.out.println("\n=== 按姓名排序 ===");
        people.stream()
              .sorted(Comparator.comparing(Person::getName))
              .forEach(System.out::println);
        
        // 2. 过滤
        System.out.println("\n=== 年龄大于25的人 ===");
        people.stream()
              .filter(p -> p.getAge() > 25)
              .forEach(System.out::println);
        
        // 3. 映射
        System.out.println("\n=== 所有人的姓名 ===");
        people.stream()
              .map(Person::getName)
              .forEach(System.out::println);
        
        // 4. 分组
        System.out.println("\n=== 按城市分组 ===");
        Map<String, List<Person>> groupedByCity = people.stream()
            .collect(Collectors.groupingBy(Person::getCity));
        groupedByCity.forEach((city, persons) -> {
            System.out.println(city + ": " + persons.size() + " 人");
        });
        
        // 5. 聚合操作
        OptionalDouble averageAge = people.stream()
            .mapToInt(Person::getAge)
            .average();
        System.out.println("\n平均年龄: " + averageAge.orElse(0));
        
        // 6. 自定义收集器
        String names = people.stream()
            .map(Person::getName)
            .collect(Collectors.joining(", ", "[", "]"));
        System.out.println("所有姓名: " + names);
    }
}

9. 函数式接口

9.1 自定义函数式接口

java
@FunctionalInterface
public interface MathOperation {
    double operate(double a, double b);
    
    // 默认方法
    default double operateAndPrint(double a, double b) {
        double result = operate(a, b);
        System.out.println("结果: " + result);
        return result;
    }
    
    // 静态方法
    static MathOperation add() {
        return (a, b) -> a + b;
    }
    
    static MathOperation multiply() {
        return (a, b) -> a * b;
    }
}

@FunctionalInterface
public interface TriFunction<T, U, V, R> {
    R apply(T t, U u, V v);
}

public class CustomFunctionalInterfaceDemo {
    
    public static void main(String[] args) {
        // 使用 Lambda 实现
        MathOperation subtract = (a, b) -> a - b;
        MathOperation divide = (a, b) -> b != 0 ? a / b : 0;
        
        System.out.println("减法: " + subtract.operate(10, 3));
        System.out.println("除法: " + divide.operate(10, 3));
        
        // 使用默认方法
        subtract.operateAndPrint(15, 5);
        
        // 使用静态方法
        MathOperation add = MathOperation.add();
        MathOperation multiply = MathOperation.multiply();
        
        System.out.println("加法: " + add.operate(5, 3));
        System.out.println("乘法: " + multiply.operate(5, 3));
        
        // 三元函数接口
        TriFunction<String, Integer, Boolean, String> formatter = 
            (str, num, upper) -> {
                String result = str + ": " + num;
                return upper ? result.toUpperCase() : result;
            };
        
        System.out.println(formatter.apply("count", 42, true));
         System.out.println(formatter.apply("value", 100, false));
     }
 }

9.2 函数式接口组合

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

public class FunctionComposition {
    
    public static void main(String[] args) {
        // Function 组合
        Function<String, String> addPrefix = s -> "前缀_" + s;
        Function<String, String> addSuffix = s -> s + "_后缀";
        Function<String, String> toUpper = String::toUpperCase;
        
        // compose: 先执行参数函数,再执行当前函数
        Function<String, String> composed1 = addSuffix.compose(addPrefix);
        System.out.println("compose: " + composed1.apply("测试"));
        
        // andThen: 先执行当前函数,再执行参数函数
        Function<String, String> composed2 = addPrefix.andThen(addSuffix);
        System.out.println("andThen: " + composed2.apply("测试"));
        
        // 链式组合
        Function<String, String> pipeline = addPrefix
            .andThen(toUpper)
            .andThen(addSuffix);
        System.out.println("链式组合: " + pipeline.apply("hello"));
        
        // Predicate 组合
        Predicate<Integer> isPositive = x -> x > 0;
        Predicate<Integer> isEven = x -> x % 2 == 0;
        Predicate<Integer> isLessThan100 = x -> x < 100;
        
        // and, or, negate 组合
        Predicate<Integer> isPositiveEven = isPositive.and(isEven);
        Predicate<Integer> isPositiveOrEven = isPositive.or(isEven);
        Predicate<Integer> isNotPositive = isPositive.negate();
        
        List<Integer> numbers = Arrays.asList(-2, -1, 0, 1, 2, 3, 4, 5, 100, 101);
        
        System.out.println("\n正数且偶数:");
        numbers.stream().filter(isPositiveEven).forEach(System.out::println);
        
        System.out.println("\n复杂条件组合:");
        Predicate<Integer> complexCondition = isPositive
            .and(isEven)
            .and(isLessThan100);
        numbers.stream().filter(complexCondition).forEach(System.out::println);
        
        // Consumer 组合
        Consumer<String> print = System.out::println;
        Consumer<String> log = s -> System.err.println("LOG: " + s);
        
        Consumer<String> printAndLog = print.andThen(log);
        printAndLog.accept("测试消息");
    }
}

10. Stream API

10.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();
        Stream<Integer> stream2 = Stream.of(1, 2, 3, 4, 5);
        Stream<Integer> stream3 = Stream.iterate(0, n -> n + 2).limit(5);
        Stream<Double> stream4 = Stream.generate(Math::random).limit(3);
        
        // 2. 中间操作(惰性求值)
        System.out.println("=== 过滤和映射 ===");
        numbers.stream()
               .filter(n -> n % 2 == 0)  // 过滤偶数
               .map(n -> n * n)          // 平方
               .forEach(System.out::println);
        
        System.out.println("\n=== 去重和排序 ===");
        List<String> words = Arrays.asList("apple", "banana", "apple", "cherry", "banana");
        words.stream()
             .distinct()                    // 去重
             .sorted()                      // 排序
             .forEach(System.out::println);
        
        System.out.println("\n=== 限制和跳过 ===");
        numbers.stream()
               .skip(3)      // 跳过前3个
               .limit(4)     // 限制4个
               .forEach(System.out::println);
        
        // 3. 终端操作(触发计算)
        System.out.println("\n=== 聚合操作 ===");
        long count = numbers.stream().filter(n -> n > 5).count();
        System.out.println("大于5的数量: " + count);
        
        OptionalInt max = numbers.stream().mapToInt(Integer::intValue).max();
        System.out.println("最大值: " + max.orElse(0));
        
        int sum = numbers.stream().mapToInt(Integer::intValue).sum();
        System.out.println("总和: " + sum);
        
        OptionalDouble average = numbers.stream().mapToInt(Integer::intValue).average();
        System.out.println("平均值: " + average.orElse(0));
        
        // 4. 查找操作
        System.out.println("\n=== 查找操作 ===");
        Optional<Integer> first = numbers.stream().filter(n -> n > 5).findFirst();
        System.out.println("第一个大于5的数: " + first.orElse(-1));
        
        Optional<Integer> any = numbers.stream().filter(n -> n > 5).findAny();
        System.out.println("任意一个大于5的数: " + any.orElse(-1));
        
        // 5. 匹配操作
        boolean allPositive = numbers.stream().allMatch(n -> n > 0);
        boolean anyEven = numbers.stream().anyMatch(n -> n % 2 == 0);
        boolean noneNegative = numbers.stream().noneMatch(n -> n < 0);
        
        System.out.println("\n=== 匹配操作 ===");
        System.out.println("全部为正数: " + allPositive);
        System.out.println("存在偶数: " + anyEven);
        System.out.println("没有负数: " + noneNegative);
    }
}

10.2 Stream 高级操作

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

public class StreamAdvanced {
    
    static class Student {
        private String name;
        private int age;
        private String major;
        private double score;
        
        public Student(String name, int age, String major, double score) {
            this.name = name;
            this.age = age;
            this.major = major;
            this.score = score;
        }
        
        // getters
        public String getName() { return name; }
        public int getAge() { return age; }
        public String getMajor() { return major; }
        public double getScore() { return score; }
        
        @Override
        public String toString() {
            return String.format("Student{name='%s', age=%d, major='%s', score=%.1f}", 
                               name, age, major, score);
        }
    }
    
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
            new Student("张三", 20, "计算机", 85.5),
            new Student("李四", 22, "数学", 92.0),
            new Student("王五", 21, "计算机", 78.5),
            new Student("赵六", 23, "物理", 88.0),
            new Student("钱七", 20, "数学", 95.5)
        );
        
        // 1. 分组操作
        System.out.println("=== 按专业分组 ===");
        Map<String, List<Student>> groupedByMajor = students.stream()
            .collect(Collectors.groupingBy(Student::getMajor));
        groupedByMajor.forEach((major, studentList) -> {
            System.out.println(major + ": " + studentList.size() + " 人");
        });
        
        // 2. 分组统计
        System.out.println("\n=== 按专业统计平均分 ===");
        Map<String, Double> averageScoreByMajor = students.stream()
            .collect(Collectors.groupingBy(
                Student::getMajor,
                Collectors.averagingDouble(Student::getScore)
            ));
        averageScoreByMajor.forEach((major, avgScore) -> {
            System.out.printf("%s: %.2f\n", major, avgScore);
        });
        
        // 3. 分区操作
        System.out.println("\n=== 按分数分区 ===");
        Map<Boolean, List<Student>> partitioned = students.stream()
            .collect(Collectors.partitioningBy(s -> s.getScore() >= 90));
        System.out.println("优秀学生 (>=90): " + partitioned.get(true).size());
        System.out.println("普通学生 (<90): " + partitioned.get(false).size());
        
        // 4. 自定义收集器
        System.out.println("\n=== 自定义收集 ===");
        String studentNames = students.stream()
            .map(Student::getName)
            .collect(Collectors.joining(", ", "学生名单: [", "]"));
        System.out.println(studentNames);
        
        // 5. 统计信息
        System.out.println("\n=== 分数统计 ===");
        DoubleSummaryStatistics scoreStats = students.stream()
            .collect(Collectors.summarizingDouble(Student::getScore));
        System.out.println("分数统计: " + scoreStats);
        
        // 6. 多级分组
        System.out.println("\n=== 按专业和年龄分组 ===");
        Map<String, Map<Integer, List<Student>>> multiGrouped = students.stream()
            .collect(Collectors.groupingBy(
                Student::getMajor,
                Collectors.groupingBy(Student::getAge)
            ));
        multiGrouped.forEach((major, ageMap) -> {
            System.out.println(major + ":");
            ageMap.forEach((age, studentList) -> {
                System.out.println("  年龄 " + age + ": " + studentList.size() + " 人");
            });
        });
        
        // 7. flatMap 操作
        System.out.println("\n=== 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("扁平化结果: " + flatList);
        
        // 8. reduce 操作
        System.out.println("\n=== reduce 操作 ===");
        Optional<Student> topStudent = students.stream()
            .reduce((s1, s2) -> s1.getScore() > s2.getScore() ? s1 : s2);
        System.out.println("最高分学生: " + topStudent.orElse(null));
        
        double totalScore = students.stream()
             .map(Student::getScore)
             .reduce(0.0, Double::sum);
         System.out.println("总分: " + totalScore);
     }
 }

10.3 并行流

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

public class ParallelStreamExample {
    
    public static void main(String[] args) {
        List<Integer> largeList = IntStream.rangeClosed(1, 1000000)
                                          .boxed()
                                          .collect(Collectors.toList());
        
        // 串行流处理
        long startTime = System.currentTimeMillis();
        long sequentialSum = largeList.stream()
                                     .mapToLong(Integer::longValue)
                                     .sum();
        long sequentialTime = System.currentTimeMillis() - startTime;
        
        // 并行流处理
        startTime = System.currentTimeMillis();
        long parallelSum = largeList.parallelStream()
                                   .mapToLong(Integer::longValue)
                                   .sum();
        long parallelTime = System.currentTimeMillis() - startTime;
        
        System.out.println("串行流结果: " + sequentialSum + ", 耗时: " + sequentialTime + "ms");
        System.out.println("并行流结果: " + parallelSum + ", 耗时: " + parallelTime + "ms");
        
        // 并行流的线程安全问题
        System.out.println("\n=== 并行流线程安全 ===");
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        // 错误示例:非线程安全
        List<Integer> unsafeResult = new ArrayList<>();
        numbers.parallelStream().forEach(unsafeResult::add); // 可能导致数据丢失
        System.out.println("非线程安全结果大小: " + unsafeResult.size());
        
        // 正确示例:使用线程安全的收集器
        List<Integer> safeResult = numbers.parallelStream()
                                         .collect(Collectors.toList());
        System.out.println("线程安全结果: " + safeResult);
        
        // 使用同步集合
        List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());
        numbers.parallelStream().forEach(synchronizedList::add);
        System.out.println("同步集合结果大小: " + synchronizedList.size());
        
        // 并行流的适用场景
        System.out.println("\n=== 并行流性能对比 ===");
        
        // CPU密集型任务
        List<Integer> testData = IntStream.rangeClosed(1, 10000)
                                         .boxed()
                                         .collect(Collectors.toList());
        
        // 串行处理
        startTime = System.nanoTime();
        double sequentialResult = testData.stream()
                                         .mapToDouble(n -> Math.sqrt(n * n * n))
                                         .sum();
        long sequentialNanos = System.nanoTime() - startTime;
        
        // 并行处理
        startTime = System.nanoTime();
        double parallelResult = testData.parallelStream()
                                       .mapToDouble(n -> Math.sqrt(n * n * n))
                                       .sum();
        long parallelNanos = System.nanoTime() - startTime;
        
        System.out.printf("串行处理: %.2f, 耗时: %.2fms\n", 
                         sequentialResult, sequentialNanos / 1_000_000.0);
        System.out.printf("并行处理: %.2f, 耗时: %.2fms\n", 
                         parallelResult, parallelNanos / 1_000_000.0);
        
        // 控制并行度
        System.out.println("\n=== 控制并行度 ===");
        System.out.println("可用处理器数量: " + Runtime.getRuntime().availableProcessors());
        
        // 使用自定义ForkJoinPool
        ForkJoinPool customThreadPool = new ForkJoinPool(2);
        try {
            long customResult = customThreadPool.submit(() ->
                numbers.parallelStream()
                       .mapToLong(Integer::longValue)
                       .sum()
            ).get();
            System.out.println("自定义线程池结果: " + customResult);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            customThreadPool.shutdown();
        }
    }
}

11. Optional 类

11.1 Optional 基础用法

java
import java.util.*;

public class OptionalBasics {
    
    public static void main(String[] args) {
        // 1. 创建 Optional
        Optional<String> empty = Optional.empty();
        Optional<String> nonEmpty = Optional.of("Hello");
        Optional<String> nullable = Optional.ofNullable(null);
        Optional<String> nullable2 = Optional.ofNullable("World");
        
        System.out.println("=== Optional 创建 ===");
        System.out.println("empty: " + empty);
        System.out.println("nonEmpty: " + nonEmpty);
        System.out.println("nullable: " + nullable);
        System.out.println("nullable2: " + nullable2);
        
        // 2. 检查值是否存在
        System.out.println("\n=== 检查值 ===");
        System.out.println("empty.isPresent(): " + empty.isPresent());
        System.out.println("nonEmpty.isPresent(): " + nonEmpty.isPresent());
        System.out.println("empty.isEmpty(): " + empty.isEmpty()); // Java 11+
        
        // 3. 获取值
        System.out.println("\n=== 获取值 ===");
        
        // 安全获取值
        if (nonEmpty.isPresent()) {
            System.out.println("值: " + nonEmpty.get());
        }
        
        // 使用 orElse
        String value1 = empty.orElse("默认值");
        String value2 = nonEmpty.orElse("默认值");
        System.out.println("empty.orElse(): " + value1);
        System.out.println("nonEmpty.orElse(): " + value2);
        
        // 使用 orElseGet(惰性求值)
        String value3 = empty.orElseGet(() -> "惰性默认值");
        System.out.println("empty.orElseGet(): " + value3);
        
        // 使用 orElseThrow
        try {
            String value4 = empty.orElseThrow(() -> new RuntimeException("值不存在"));
        } catch (RuntimeException e) {
            System.out.println("异常: " + e.getMessage());
        }
        
        // 4. 条件执行
        System.out.println("\n=== 条件执行 ===");
        nonEmpty.ifPresent(s -> System.out.println("值存在: " + s));
        empty.ifPresent(s -> System.out.println("这不会执行"));
        
        // Java 9+ ifPresentOrElse
        nonEmpty.ifPresentOrElse(
            s -> System.out.println("存在值: " + s),
            () -> System.out.println("值不存在")
        );
        
        empty.ifPresentOrElse(
            s -> System.out.println("这不会执行"),
            () -> System.out.println("空值处理")
        );
    }
}

11.2 Optional 高级用法

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

public class OptionalAdvanced {
    
    static class Person {
        private String name;
        private Optional<String> email;
        private Optional<Address> address;
        
        public Person(String name, String email, Address address) {
            this.name = name;
            this.email = Optional.ofNullable(email);
            this.address = Optional.ofNullable(address);
        }
        
        public String getName() { return name; }
        public Optional<String> getEmail() { return email; }
        public Optional<Address> getAddress() { return address; }
    }
    
    static class Address {
        private String street;
        private String city;
        
        public Address(String street, String city) {
            this.street = street;
            this.city = city;
        }
        
        public String getStreet() { return street; }
        public String getCity() { return city; }
    }
    
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("张三", "zhang@example.com", new Address("中山路", "北京")),
            new Person("李四", null, null),
            new Person("王五", "wang@example.com", new Address("人民路", "上海"))
        );
        
        // 1. map 操作
        System.out.println("=== map 操作 ===");
        Optional<String> name = Optional.of("hello");
        Optional<String> upperName = name.map(String::toUpperCase);
        System.out.println("转大写: " + upperName.orElse("无值"));
        
        Optional<Integer> length = name.map(String::length);
        System.out.println("字符串长度: " + length.orElse(0));
        
        // 2. flatMap 操作
        System.out.println("\n=== flatMap 操作 ===");
        people.forEach(person -> {
            String email = person.getEmail()
                                .map(String::toUpperCase)
                                .orElse("无邮箱");
            System.out.println(person.getName() + " 的邮箱: " + email);
            
            String city = person.getAddress()
                               .map(Address::getCity)
                               .orElse("未知城市");
            System.out.println(person.getName() + " 的城市: " + city);
        });
        
        // 3. filter 操作
        System.out.println("\n=== filter 操作 ===");
        Optional<String> longEmail = Optional.of("very.long.email@example.com")
                                           .filter(email -> email.length() > 10);
        System.out.println("长邮箱: " + longEmail.orElse("邮箱太短"));
        
        Optional<String> shortEmail = Optional.of("a@b.com")
                                            .filter(email -> email.length() > 10);
        System.out.println("短邮箱: " + shortEmail.orElse("邮箱太短"));
        
        // 4. 链式操作
        System.out.println("\n=== 链式操作 ===");
        people.forEach(person -> {
            String result = person.getEmail()
                                 .filter(email -> email.contains("@"))
                                 .map(email -> email.substring(0, email.indexOf("@")))
                                 .map(String::toUpperCase)
                                 .orElse("无效用户名");
            System.out.println(person.getName() + " 的用户名: " + result);
        });
        
        // 5. Optional 与 Stream 结合
        System.out.println("\n=== Optional 与 Stream ===");
        List<String> emails = people.stream()
                                   .map(Person::getEmail)
                                   .filter(Optional::isPresent)
                                   .map(Optional::get)
                                   .collect(Collectors.toList());
        System.out.println("所有邮箱: " + emails);
        
        // Java 9+ 更简洁的写法
        List<String> emails2 = people.stream()
                                    .map(Person::getEmail)
                                    .flatMap(Optional::stream)
                                    .collect(Collectors.toList());
        System.out.println("所有邮箱(Java 9+): " + emails2);
        
        // 6. Optional 的组合
        System.out.println("\n=== Optional 组合 ===");
        Optional<String> firstName = Optional.of("张");
        Optional<String> lastName = Optional.of("三");
        
        // 组合两个 Optional
        Optional<String> fullName = firstName.flatMap(first ->
            lastName.map(last -> first + last)
        );
        System.out.println("全名: " + fullName.orElse("未知"));
        
        // 7. 实用工具方法
        System.out.println("\n=== 实用工具 ===");
        
        // 安全的字符串转整数
        System.out.println("字符串转整数: " + safeParseInt("123").orElse(-1));
        System.out.println("无效字符串转整数: " + safeParseInt("abc").orElse(-1));
        
        // 安全的数组访问
        String[] array = {"a", "b", "c"};
        System.out.println("数组[1]: " + safeArrayAccess(array, 1).orElse("越界"));
        System.out.println("数组[5]: " + safeArrayAccess(array, 5).orElse("越界"));
    }
    
    // 安全的字符串转整数
    public static Optional<Integer> safeParseInt(String str) {
        try {
            return Optional.of(Integer.parseInt(str));
        } catch (NumberFormatException e) {
            return Optional.empty();
        }
    }
    
    // 安全的数组访问
    public static <T> Optional<T> safeArrayAccess(T[] array, int index) {
        if (index >= 0 && index < array.length) {
            return Optional.ofNullable(array[index]);
        }
        return Optional.empty();
    }
}

12. 总结与最佳实践

12.1 设计原则

  1. 单一职责原则:每个类应该只有一个改变的理由
  2. 开闭原则:对扩展开放,对修改关闭
  3. 里氏替换原则:子类应该能够替换父类
  4. 接口隔离原则:不应该强迫客户依赖它们不使用的方法
  5. 依赖倒置原则:高层模块不应该依赖低层模块

12.2 编码最佳实践

java
// 1. 使用 Optional 避免 null 检查
public Optional<User> findUserById(Long id) {
    // 返回 Optional 而不是 null
    return userRepository.findById(id);
}

// 2. 使用 Stream API 进行集合操作
List<String> activeUserNames = users.stream()
    .filter(User::isActive)
    .map(User::getName)
    .collect(Collectors.toList());

// 3. 使用函数式接口提高代码可读性
Predicate<User> isAdult = user -> user.getAge() >= 18;
Function<User, String> getUserInfo = user -> 
    user.getName() + " (" + user.getAge() + ")";

// 4. 合理使用泛型
public <T extends Comparable<T>> T findMax(List<T> list) {
    return list.stream().max(Comparable::compareTo).orElse(null);
}

// 5. 使用枚举替代常量
public enum Status {
    ACTIVE("激活"),
    INACTIVE("未激活"),
    SUSPENDED("暂停");
    
    private final String description;
    
    Status(String description) {
        this.description = description;
    }
    
    public String getDescription() {
        return description;
    }
}

12.3 性能优化建议

  1. 合理使用并行流:仅在数据量大且CPU密集型任务时使用
  2. 避免过度使用反射:反射会影响性能,考虑使用注解处理器
  3. 正确使用泛型:避免类型擦除带来的性能问题
  4. 合理设计类层次:避免过深的继承层次
  5. 使用适当的集合类型:根据使用场景选择合适的集合实现

12.4 安全注意事项

  1. 避免反射安全漏洞:限制反射的使用范围
  2. 正确处理异常:不要忽略或隐藏异常
  3. 使用不可变对象:提高线程安全性
  4. 验证输入参数:使用 Optional 和断言进行参数验证
  5. 遵循最小权限原则:合理设置访问修饰符