第二阶段:Java进阶技能③Java新特性

Java15新特性一览 作者:Java技术栈 JDK 15 2020/09/15 如期而至! 这个时间牛逼啊,和苹果发布会同天? OracleJDK 15 发布地址: https://www.oracle.com/java/technologies/javase/15all-relnotes.html OpenJDK 15 发布地址: https://openjdk.java.net/projects/jdk/15/ OracleJDK 和 OpenJDK 两者的区别这里不撰述了,不清楚的请点击这里进行查 阅读详情

🚀 第二阶段:Java进阶技能③Java新特性

💡 学习目标:掌握Java 8+的现代特性,包括Lambda表达式、Stream API、新日期时间API和模块化系统,提升编程效率和代码质量

🔗 Lambda表达式与函数式编程

🎯 Lambda表达式概述

🌟 Lambda表达式:Java 8引入的函数式编程特性,允许将函数作为参数传递,简化代码编写

✨ Lambda表达式的核心优势
优势说明示例
📝 简化代码减少样板代码(x, y) -> x + y 替代匿名内部类
🚀 提高可读性代码更加简洁明了函数式风格更直观
🔧 支持函数式编程函数作为一等公民高阶函数、函数组合
⚡ 性能优化编译器优化避免创建多余的匿名类
🏗️ Lambda表达式语法

📋 基本语法格式

// 完整格式
(参数列表) -> {
    // 方法体
    return 结果;
}

// 简化格式(单表达式)
(参数列表) -> 表达式

// 单参数可省略括号
参数 -> 表达式

// 无参数
() -> 表达式

💻 Lambda表达式实战

🎯 基础Lambda示例

🎯 示例1:Lambda表达式基础用法

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

public class LambdaBasicsDemo {
    
    public static void main(String[] args) {
        System.out.println("=== Lambda表达式基础演示 ===");
        
        // 1. 替代匿名内部类
        System.out.println("\n1. 线程创建对比:");
        
        // 传统方式
        Thread oldThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("传统方式创建线程");
            }
        });
        
        // Lambda方式
        Thread newThread = new Thread(() -> {
            System.out.println("Lambda方式创建线程");
        });
        
        oldThread.start();
        newThread.start();
        
        // 2. 集合操作
        System.out.println("\n2. 集合排序对比:");
        List<String> names = Arrays.asList("张三", "李四", "王五", "赵六");
        
        // 传统方式排序
        List<String> traditionalSort = new ArrayList<>(names);
        Collections.sort(traditionalSort, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return s1.length() - s2.length();
            }
        });
        System.out.println("传统排序结果: " + traditionalSort);
        
        // Lambda方式排序
        List<String> lambdaSort = new ArrayList<>(names);
        lambdaSort.sort((s1, s2) -> s1.length() - s2.length());
        System.out.println("Lambda排序结果: " + lambdaSort);
        
        // 3. 函数式接口使用
        System.out.println("\n3. 函数式接口演示:");
        
        // Predicate - 判断条件
        Predicate<String> isLongName = name -> name.length() > 2;
        System.out.println("张三 是长名字吗? " + isLongName.test("张三"));
        System.out.println("张三丰 是长名字吗? " + isLongName.test("张三丰"));
        
        // Function - 转换函数
        Function<String, Integer> getLength = String::length;
        System.out.println("'Hello World' 的长度: " + getLength.apply("Hello World"));
        
        // Consumer - 消费者
        Consumer<String> printer = System.out::println;
        names.forEach(printer);
        
        // Supplier - 供应者
        Supplier<String> randomName = () -> {
            String[] namePool = {"小明", "小红", "小刚", "小丽"};
            return namePool[new Random().nextInt(namePool.length)];
        };
        System.out.println("随机名字: " + randomName.get());
    }
}
🔧 高级Lambda应用

🎯 示例2:高级Lambda特性

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

public class AdvancedLambdaDemo {
    
    // 自定义函数式接口
    @FunctionalInterface
    interface Calculator {
        double calculate(double a, double b);
        
        // 默认方法
        default String getDescription() {
            return "数学计算器";
        }
    }
    
    // 高阶函数示例
    public static Function<Integer, Integer> createMultiplier(int factor) {
        return x -> x * factor;
    }
    
    // 函数组合示例
    public static void demonstrateFunctionComposition() {
        System.out.println("=== 函数组合演示 ===");
        
        Function<String, String> addPrefix = s -> "前缀-" + s;
        Function<String, String> addSuffix = s -> s + "-后缀";
        Function<String, String> toUpper = String::toUpperCase;
        
        // 函数组合
        Function<String, String> combined = addPrefix
            .andThen(addSuffix)
            .andThen(toUpper);
        
        String result = combined.apply("测试");
        System.out.println("组合函数结果: " + result);
    }
    
    public static void main(String[] args) {
        System.out.println("=== 高级Lambda特性演示 ===");
        
        // 1. 自定义函数式接口
        System.out.println("\n1. 自定义函数式接口:");
        Calculator add = (a, b) -> a + b;
        Calculator multiply = (a, b) -> a * b;
        Calculator power = Math::pow;
        
        System.out.println("5 + 3 = " + add.calculate(5, 3));
        System.out.println("5 * 3 = " + multiply.calculate(5, 3));
        System.out.println("5 ^ 3 = " + power.calculate(5, 3));
        System.out.println("描述: " + add.getDescription());
        
        // 2. 高阶函数
        System.out.println("\n2. 高阶函数:");
        Function<Integer, Integer> doubler = createMultiplier(2);
        Function<Integer, Integer> tripler = createMultiplier(3);
        
        System.out.println("10 * 2 = " + doubler.apply(10));
        System.out.println("10 * 3 = " + tripler.apply(10));
        
        // 3. 函数组合
        demonstrateFunctionComposition();
        
        // 4. 闭包示例
        System.out.println("\n4. 闭包示例:");
        int baseValue = 100;
        Function<Integer, Integer> addBase = x -> x + baseValue; // 捕获外部变量
        System.out.println("50 + 100 = " + addBase.apply(50));
        
        // 5. 方法引用
        System.out.println("\n5. 方法引用:");
        List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
        
        // 静态方法引用
        words.sort(String::compareToIgnoreCase);
        System.out.println("排序后: " + words);
        
        // 实例方法引用
        words.forEach(System.out::println);
        
        // 构造器引用
        Supplier<List<String>> listSupplier = ArrayList::new;
        List<String> newList = listSupplier.get();
        System.out.println("新列表: " + newList);
    }
}

🌊 Stream API详解

🎯 Stream API概述

🌟 Stream API:Java 8引入的数据处理API,提供声明式的数据操作方式,支持函数式编程风格

✨ Stream API核心特性
🌊 Stream API特性
│
├── 🔄 声明式编程
│   ├── 描述"做什么"而非"怎么做"
│   └── 代码更简洁易读
│
├── 🔗 链式操作
│   ├── 中间操作(Intermediate)
│   └── 终端操作(Terminal)
│
├── ⚡ 延迟执行
│   ├── 中间操作不立即执行
│   └── 终端操作触发计算
│
└── 🚀 并行处理
    ├── 自动并行化
    └── 充分利用多核CPU

💻 Stream基础操作

🎯 创建Stream和基本操作

🎯 示例3:Stream基础操作

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

public class StreamBasicsDemo {
    
    public static void main(String[] args) {
        System.out.println("=== Stream基础操作演示 ===");
        
        // 1. 创建Stream的多种方式
        System.out.println("\n1. 创建Stream:");
        
        // 从集合创建
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Stream<Integer> fromList = numbers.stream();
        
        // 从数组创建
        String[] words = {"apple", "banana", "cherry"};
        Stream<String> fromArray = Arrays.stream(words);
        
        // 使用Stream.of()
        Stream<String> fromValues = Stream.of("Java", "Python", "JavaScript");
        
        // 无限流
        Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);
        Stream<Double> randomStream = Stream.generate(Math::random);
        
        // 2. 过滤操作(filter)
        System.out.println("\n2. 过滤操作:");
        List<Integer> evenNumbers = numbers.stream()
            .filter(n -> n % 2 == 0)
            .collect(Collectors.toList());
        System.out.println("偶数: " + evenNumbers);
        
        // 3. 映射操作(map)
        System.out.println("\n3. 映射操作:");
        List<Integer> squares = numbers.stream()
            .map(n -> n * n)
            .collect(Collectors.toList());
        System.out.println("平方数: " + squares);
        
        // 4. 排序操作(sorted)
        System.out.println("\n4. 排序操作:");
        List<String> sortedWords = Arrays.stream(words)
            .sorted()
            .collect(Collectors.toList());
        System.out.println("排序后: " + sortedWords);
        
        // 5. 去重操作(distinct)
        System.out.println("\n5. 去重操作:");
        List<Integer> duplicates = Arrays.asList(1, 2, 2, 3, 3, 3, 4, 4, 5);
        List<Integer> unique = duplicates.stream()
            .distinct()
            .collect(Collectors.toList());
        System.out.println("去重后: " + unique);
        
        // 6. 限制操作(limit/skip)
        System.out.println("\n6. 限制操作:");
        List<Integer> first5 = numbers.stream()
            .limit(5)
            .collect(Collectors.toList());
        System.out.println("前5个: " + first5);
        
        List<Integer> skip5 = numbers.stream()
            .skip(5)
            .collect(Collectors.toList());
        System.out.println("跳过前5个: " + skip5);
    }
}
🔧 Stream高级操作

🎯 示例4:Stream高级特性

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

public class AdvancedStreamDemo {
    
    // 学生类
    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;
        }
        
        // getter方法
        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) {
        System.out.println("=== Stream高级操作演示 ===");
        
        // 创建学生数据
        List<Student> students = Arrays.asList(
            new Student("张三", 20, "计算机", 85.5),
            new Student("李四", 21, "数学", 92.0),
            new Student("王五", 19, "计算机", 78.5),
            new Student("赵六", 22, "物理", 88.0),
            new Student("钱七", 20, "数学", 95.5),
            new Student("孙八", 21, "计算机", 82.0)
        );
        
        // 1. 分组操作(groupingBy)
        System.out.println("\n1. 按专业分组:");
        Map<String, List<Student>> byMajor = students.stream()
            .collect(Collectors.groupingBy(Student::getMajor));
        byMajor.forEach((major, studentList) -> {
            System.out.println(major + ": " + studentList.size() + "人");
        });
        
        // 2. 分区操作(partitioningBy)
        System.out.println("\n2. 按成绩分区(>=90分):");
        Map<Boolean, List<Student>> byScore = students.stream()
            .collect(Collectors.partitioningBy(s -> s.getScore() >= 90));
        System.out.println("优秀学生: " + byScore.get(true).size() + "人");
        System.out.println("普通学生: " + byScore.get(false).size() + "人");
        
        // 3. 统计操作
        System.out.println("\n3. 成绩统计:");
        DoubleSummaryStatistics scoreStats = students.stream()
            .mapToDouble(Student::getScore)
            .summaryStatistics();
        System.out.println("平均分: " + scoreStats.getAverage());
        System.out.println("最高分: " + scoreStats.getMax());
        System.out.println("最低分: " + scoreStats.getMin());
        System.out.println("总人数: " + scoreStats.getCount());
        
        // 4. 查找操作
        System.out.println("\n4. 查找操作:");
        Optional<Student> topStudent = students.stream()
            .max(Comparator.comparing(Student::getScore));
        topStudent.ifPresent(s -> System.out.println("最高分学生: " + s));
        
        boolean hasExcellent = students.stream()
            .anyMatch(s -> s.getScore() >= 95);
        System.out.println("是否有95分以上学生: " + hasExcellent);
        
        // 5. 归约操作(reduce)
        System.out.println("\n5. 归约操作:");
        double totalScore = students.stream()
            .mapToDouble(Student::getScore)
            .reduce(0.0, Double::sum);
        System.out.println("总分: " + totalScore);
        
        Optional<Student> oldestStudent = students.stream()
            .reduce((s1, s2) -> s1.getAge() > s2.getAge() ? s1 : s2);
        oldestStudent.ifPresent(s -> System.out.println("年龄最大学生: " + s));
        
        // 6. 并行流
        System.out.println("\n6. 并行流性能对比:");
        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("顺序流耗时: " + sequentialTime + "ms, 结果: " + sequentialSum);
        System.out.println("并行流耗时: " + parallelTime + "ms, 结果: " + parallelSum);
    }
}

⏰ 新日期时间API

🎯 新日期时间API概述

🌟 新日期时间API:Java 8引入的java.time包,解决了传统Date和Calendar类的诸多问题

✨ 新API的核心优势
特性传统API问题新API解决方案
🔒 不可变性Date类可变,线程不安全所有类都是不可变的
🎯 类型安全月份从0开始,容易出错月份从1开始,更直观
📅 功能完整功能分散在多个类中职责明确,功能集中
🌍 时区支持时区处理复杂内置完善的时区支持
📖 可读性API设计不够直观链式调用,语义清晰

💻 核心日期时间类

🎯 基础日期时间操作

🎯 示例5:新日期时间API基础

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class DateTimeBasicsDemo {
    
    public static void main(String[] args) {
        System.out.println("=== 新日期时间API演示 ===");
        
        // 1. 基本日期时间类
        System.out.println("\n1. 基本日期时间类:");
        
        // LocalDate - 日期
        LocalDate today = LocalDate.now();
        LocalDate birthday = LocalDate.of(1990, 5, 15);
        System.out.println("今天: " + today);
        System.out.println("生日: " + birthday);
        
        // LocalTime - 时间
        LocalTime now = LocalTime.now();
        LocalTime meetingTime = LocalTime.of(14, 30, 0);
        System.out.println("现在时间: " + now);
        System.out.println("会议时间: " + meetingTime);
        
        // LocalDateTime - 日期时间
        LocalDateTime currentDateTime = LocalDateTime.now();
        LocalDateTime appointmentTime = LocalDateTime.of(2024, 12, 25, 10, 30);
        System.out.println("当前日期时间: " + currentDateTime);
        System.out.println("预约时间: " + appointmentTime);
        
        // 2. 日期计算
        System.out.println("\n2. 日期计算:");
        LocalDate nextWeek = today.plusWeeks(1);
        LocalDate lastMonth = today.minusMonths(1);
        LocalDate nextYear = today.plusYears(1);
        
        System.out.println("下周: " + nextWeek);
        System.out.println("上个月: " + lastMonth);
        System.out.println("明年: " + nextYear);
        
        // 3. 时间间隔计算
        System.out.println("\n3. 时间间隔:");
        long daysBetween = ChronoUnit.DAYS.between(birthday, today);
        long yearsBetween = ChronoUnit.YEARS.between(birthday, today);
        
        System.out.println("距离生日已过: " + daysBetween + " 天");
        System.out.println("年龄: " + yearsBetween + " 岁");
        
        // 4. 日期比较
        System.out.println("\n4. 日期比较:");
        LocalDate date1 = LocalDate.of(2024, 1, 1);
        LocalDate date2 = LocalDate.of(2024, 12, 31);
        
        System.out.println("date1 在 date2 之前: " + date1.isBefore(date2));
        System.out.println("date1 在 date2 之后: " + date1.isAfter(date2));
        System.out.println("date1 等于 today: " + date1.isEqual(today));
        
        // 5. 获取日期信息
        System.out.println("\n5. 日期信息:");
        System.out.println("年份: " + today.getYear());
        System.out.println("月份: " + today.getMonth() + " (" + today.getMonthValue() + ")");
        System.out.println("日期: " + today.getDayOfMonth());
        System.out.println("星期: " + today.getDayOfWeek());
        System.out.println("一年中的第几天: " + today.getDayOfYear());
    }
}
🌍 时区和格式化

🎯 示例6:时区处理和格式化

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;

public class DateTimeAdvancedDemo {
    
    public static void main(String[] args) {
        System.out.println("=== 高级日期时间操作演示 ===");
        
        // 1. 时区处理
        System.out.println("\n1. 时区处理:");
        
        // 带时区的日期时间
        ZonedDateTime beijingTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        ZonedDateTime newYorkTime = ZonedDateTime.now(ZoneId.of("America/New_York"));
        ZonedDateTime londonTime = ZonedDateTime.now(ZoneId.of("Europe/London"));
        
        System.out.println("北京时间: " + beijingTime);
        System.out.println("纽约时间: " + newYorkTime);
        System.out.println("伦敦时间: " + londonTime);
        
        // 时区转换
        ZonedDateTime beijingToNewYork = beijingTime.withZoneSameInstant(ZoneId.of("America/New_York"));
        System.out.println("北京时间转纽约时间: " + beijingToNewYork);
        
        // 2. 日期格式化
        System.out.println("\n2. 日期格式化:");
        LocalDateTime now = LocalDateTime.now();
        
        // 预定义格式
        System.out.println("ISO格式: " + now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        System.out.println("基本ISO格式: " + now.format(DateTimeFormatter.BASIC_ISO_DATE));
        
        // 本地化格式
        System.out.println("中文长格式: " + now.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(Locale.CHINA)));
        System.out.println("中文短格式: " + now.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withLocale(Locale.CHINA)));
        
        // 自定义格式
        DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        System.out.println("自定义格式: " + now.format(customFormatter));
        
        DateTimeFormatter englishFormatter = DateTimeFormatter.ofPattern("EEEE, MMMM dd, yyyy 'at' HH:mm", Locale.ENGLISH);
        System.out.println("英文格式: " + now.format(englishFormatter));
        
        // 3. 字符串解析
        System.out.println("\n3. 字符串解析:");
        String dateString = "2024-12-25 15:30:45";
        LocalDateTime parsed = LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println("解析结果: " + parsed);
        
        // 4. Period和Duration
        System.out.println("\n4. 时间段计算:");
        
        // Period - 日期间隔
        LocalDate startDate = LocalDate.of(2020, 1, 1);
        LocalDate endDate = LocalDate.of(2024, 12, 31);
        Period period = Period.between(startDate, endDate);
        System.out.println("时间间隔: " + period.getYears() + "年" + period.getMonths() + "月" + period.getDays() + "天");
        
        // Duration - 时间间隔
        LocalTime startTime = LocalTime.of(9, 0);
        LocalTime endTime = LocalTime.of(17, 30);
        Duration duration = Duration.between(startTime, endTime);
        System.out.println("工作时长: " + duration.toHours() + "小时" + (duration.toMinutes() % 60) + "分钟");
        
        // 5. 实用工具方法
        System.out.println("\n5. 实用工具:");
        
        // 判断闰年
        System.out.println("2024年是闰年: " + Year.of(2024).isLeap());
        System.out.println("2023年是闰年: " + Year.of(2023).isLeap());
        
        // 月份天数
        YearMonth yearMonth = YearMonth.of(2024, 2);
        System.out.println("2024年2月有 " + yearMonth.lengthOfMonth() + " 天");
        
        // 一年的天数
        Year year2024 = Year.of(2024);
        System.out.println("2024年有 " + year2024.length() + " 天");
    }
}

🔧 Optional类详解

🎯 Optional概述

🌟 Optional:Java 8引入的容器类,用于优雅地处理可能为null的值,避免NullPointerException

✨ Optional的核心优势
优势传统方式问题Optional解决方案
🛡️ 空值安全容易出现NPE强制处理空值情况
📖 代码可读性大量null检查链式调用更清晰
🎯 意图明确不知道是否可能为null明确表示可能为空
🔧 函数式风格命令式编程支持函数式操作

💻 Optional实战应用

🎯 Optional基础操作

🎯 示例7:Optional基础用法

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

public class OptionalBasicsDemo {
    
    // 用户类
    static class User {
        private String name;
        private String email;
        private Integer age;
        
        public User(String name, String email, Integer age) {
            this.name = name;
            this.email = email;
            this.age = age;
        }
        
        public String getName() { return name; }
        public String getEmail() { return email; }
        public Integer getAge() { return age; }
        
        @Override
        public String toString() {
            return String.format("User{name='%s', email='%s', age=%d}", name, email, age);
        }
    }
    
    // 模拟数据库查询
    public static Optional<User> findUserById(int id) {
        Map<Integer, User> users = Map.of(
            1, new User("张三", "zhangsan@example.com", 25),
            2, new User("李四", "lisi@example.com", 30),
            3, new User("王五", null, 28) // 邮箱为空
        );
        return Optional.ofNullable(users.get(id));
    }
    
    public static void main(String[] args) {
        System.out.println("=== Optional基础操作演示 ===");
        
        // 1. 创建Optional
        System.out.println("\n1. 创建Optional:");
        
        // 创建空Optional
        Optional<String> empty = Optional.empty();
        System.out.println("空Optional: " + empty);
        
        // 创建非空Optional
        Optional<String> nonEmpty = Optional.of("Hello");
        System.out.println("非空Optional: " + nonEmpty);
        
        // 创建可能为空的Optional
        Optional<String> nullable = Optional.ofNullable(null);
        System.out.println("可能为空的Optional: " + nullable);
        
        // 2. 检查值是否存在
        System.out.println("\n2. 检查值:");
        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("\n3. 获取值:");
        
        // 安全获取值
        if (nonEmpty.isPresent()) {
            System.out.println("值: " + nonEmpty.get());
        }
        
        // 提供默认值
        String value1 = empty.orElse("默认值");
        String value2 = nonEmpty.orElse("默认值");
        System.out.println("empty.orElse(): " + value1);
        System.out.println("nonEmpty.orElse(): " + value2);
        
        // 延迟计算默认值
        String value3 = empty.orElseGet(() -> "计算得到的默认值");
        System.out.println("empty.orElseGet(): " + value3);
        
        // 4. 条件执行
        System.out.println("\n4. 条件执行:");
        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("值不存在")
        );
        
        // 5. 实际应用示例
        System.out.println("\n5. 实际应用:");
        
        // 查找用户
        Optional<User> user1 = findUserById(1);
        Optional<User> user999 = findUserById(999);
        
        // 传统方式处理
        System.out.println("传统方式:");
        User u1 = user1.orElse(null);
        if (u1 != null) {
            System.out.println("找到用户: " + u1.getName());
        } else {
            System.out.println("用户不存在");
        }
        
        // Optional方式处理
        System.out.println("Optional方式:");
        user1.ifPresentOrElse(
            user -> System.out.println("找到用户: " + user.getName()),
            () -> System.out.println("用户不存在")
        );
        
        user999.ifPresentOrElse(
            user -> System.out.println("找到用户: " + user.getName()),
            () -> System.out.println("用户不存在")
        );
    }
}
🔧 Optional高级操作

🎯 示例8:Optional高级特性

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

public class OptionalAdvancedDemo {

    static class Address {
        private String street;
        private String city;
        private String country;

        public Address(String street, String city, String country) {
            this.street = street;
            this.city = city;
            this.country = country;
        }

        public String getStreet() { return street; }
        public String getCity() { return city; }
        public String getCountry() { return country; }

        @Override
        public String toString() {
            return String.format("%s, %s, %s", street, city, country);
        }
    }

    static class Person {
        private String name;
        private Optional<Address> address;
        private Optional<String> phone;

        public Person(String name, Address address, String phone) {
            this.name = name;
            this.address = Optional.ofNullable(address);
            this.phone = Optional.ofNullable(phone);
        }

        public String getName() { return name; }
        public Optional<Address> getAddress() { return address; }
        public Optional<String> getPhone() { return phone; }
    }

    public static void main(String[] args) {
        System.out.println("=== Optional高级操作演示 ===");

        // 创建测试数据
        Person person1 = new Person("张三",
            new Address("中关村大街1号", "北京", "中国"),
            "13800138000");
        Person person2 = new Person("李四", null, null);

        // 1. map操作 - 转换值
        System.out.println("\n1. map操作:");
        Optional<String> city1 = Optional.of(person1)
            .map(Person::getAddress)
            .flatMap(addr -> addr)
            .map(Address::getCity);

        System.out.println("张三的城市: " + city1.orElse("未知"));

        Optional<String> city2 = Optional.of(person2)
            .map(Person::getAddress)
            .flatMap(addr -> addr)
            .map(Address::getCity);

        System.out.println("李四的城市: " + city2.orElse("未知"));

        // 2. flatMap操作 - 扁平化嵌套Optional
        System.out.println("\n2. flatMap操作:");
        Optional<String> phone1 = Optional.of(person1)
            .flatMap(Person::getPhone);

        Optional<String> phone2 = Optional.of(person2)
            .flatMap(Person::getPhone);

        System.out.println("张三的电话: " + phone1.orElse("无电话"));
        System.out.println("李四的电话: " + phone2.orElse("无电话"));

        // 3. filter操作 - 条件过滤
        System.out.println("\n3. filter操作:");
        Optional<Person> beijingPerson = Optional.of(person1)
            .filter(p -> p.getAddress()
                .map(Address::getCity)
                .orElse("")
                .equals("北京"));

        beijingPerson.ifPresentOrElse(
            p -> System.out.println(p.getName() + " 住在北京"),
            () -> System.out.println("不住在北京")
        );

        // 4. 链式操作组合
        System.out.println("\n4. 链式操作:");
        String result = Optional.of(person1)
            .flatMap(Person::getAddress)
            .map(Address::getCountry)
            .filter(country -> country.equals("中国"))
            .map(country -> "国内用户")
            .orElse("国外用户");

        System.out.println("用户类型: " + result);

        // 5. Optional与Stream结合
        System.out.println("\n5. Optional与Stream:");
        List<Person> people = Arrays.asList(person1, person2);

        // 获取所有有效的城市
        List<String> cities = people.stream()
            .map(Person::getAddress)
            .filter(Optional::isPresent)
            .map(Optional::get)
            .map(Address::getCity)
            .distinct()
            .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

        System.out.println("所有城市: " + cities);

        // Java 9+ Optional.stream()
        List<String> phones = people.stream()
            .map(Person::getPhone)
            .flatMap(Optional::stream)
            .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

        System.out.println("所有电话: " + phones);

        // 6. 异常处理
        System.out.println("\n6. 异常处理:");
        Optional<Integer> number = parseInteger("123");
        Optional<Integer> invalid = parseInteger("abc");

        System.out.println("解析 '123': " + number.orElse(-1));
        System.out.println("解析 'abc': " + invalid.orElse(-1));

        // 7. Optional最佳实践
        System.out.println("\n7. 最佳实践示例:");
        demonstrateBestPractices();
    }

    // 安全的字符串转整数
    public static Optional<Integer> parseInteger(String str) {
        try {
            return Optional.of(Integer.parseInt(str));
        } catch (NumberFormatException e) {
            return Optional.empty();
        }
    }

    // Optional最佳实践
    public static void demonstrateBestPractices() {
        // ✅ 好的做法
        Optional<String> goodExample = Optional.ofNullable(getValue())
            .filter(s -> !s.isEmpty())
            .map(String::toUpperCase);

        goodExample.ifPresentOrElse(
            value -> System.out.println("处理值: " + value),
            () -> System.out.println("值为空或无效")
        );

        // ❌ 避免的做法
        // 不要这样做:
        // if (optional.isPresent()) {
        //     return optional.get();
        // } else {
        //     return defaultValue;
        // }
        // 应该这样做:
        String result = goodExample.orElse("默认值");
        System.out.println("最终结果: " + result);
    }

    private static String getValue() {
        return Math.random() > 0.5 ? "hello" : null;
    }
}

📦 模块化系统(Java 9+)

🎯 模块化系统概述

🌟 模块化系统(JPMS):Java 9引入的模块化系统,提供更好的封装性、可靠性和可维护性

✨ 模块化的核心优势
📦 模块化系统特性
│
├── 🔒 强封装
│   ├── 明确的API边界
│   └── 隐藏内部实现
│
├── 🎯 可靠配置
│   ├── 编译时依赖检查
│   └── 避免运行时错误
│
├── 🚀 性能优化
│   ├── 更小的运行时镜像
│   └── 启动时间优化
│
└── 🛠️ 工具支持
    ├── jlink创建自定义运行时
    └── 更好的IDE支持

💻 模块化实战

🎯 基础模块定义

🎯 示例9:模块化项目结构

// 项目结构示例
/*
my-modular-app/
├── src/
│   ├── com.example.utils/
│   │   ├── module-info.java
│   │   └── com/example/utils/
│   │       ├── StringUtils.java
│   │       └── MathUtils.java
│   ├── com.example.service/
│   │   ├── module-info.java
│   │   └── com/example/service/
│   │       ├── UserService.java
│   │       └── impl/
│   │           └── UserServiceImpl.java
│   └── com.example.app/
│       ├── module-info.java
│       └── com/example/app/
│           └── Application.java
*/

// 1. 工具模块 (com.example.utils)
// module-info.java
module com.example.utils {
    // 导出包,使其他模块可以访问
    exports com.example.utils;
}

// StringUtils.java
package com.example.utils;

public class StringUtils {

    public static boolean isEmpty(String str) {
        return str == null || str.trim().isEmpty();
    }

    public static String capitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
    }

    public static String reverse(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return new StringBuilder(str).reverse().toString();
    }
}

// MathUtils.java
package com.example.utils;

public class MathUtils {

    public static boolean isPrime(int number) {
        if (number < 2) return false;
        for (int i = 2; i <= Math.sqrt(number); i++) {
            if (number % i == 0) return false;
        }
        return true;
    }

    public static int gcd(int a, int b) {
        while (b != 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
}

// 2. 服务模块 (com.example.service)
// module-info.java
module com.example.service {
    // 依赖工具模块
    requires com.example.utils;

    // 导出服务接口
    exports com.example.service;

    // 不导出实现包,保持封装性
    // com.example.service.impl 包对外不可见
}

// UserService.java
package com.example.service;

import java.util.List;
import java.util.Optional;

public interface UserService {
    Optional<User> findById(Long id);
    List<User> findAll();
    User save(User user);
    void deleteById(Long id);
}

// User.java
package com.example.service;

public class User {
    private Long id;
    private String name;
    private String email;

    public User(Long id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    // getter和setter方法
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }

    @Override
    public String toString() {
        return String.format("User{id=%d, name='%s', email='%s'}", id, name, email);
    }
}

// UserServiceImpl.java (内部实现,不对外暴露)
package com.example.service.impl;

import com.example.service.User;
import com.example.service.UserService;
import com.example.utils.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

public class UserServiceImpl implements UserService {
    private final Map<Long, User> users = new ConcurrentHashMap<>();
    private final AtomicLong idGenerator = new AtomicLong(1);

    public UserServiceImpl() {
        // 初始化一些测试数据
        save(new User(null, "张三", "zhangsan@example.com"));
        save(new User(null, "李四", "lisi@example.com"));
    }

    @Override
    public Optional<User> findById(Long id) {
        return Optional.ofNullable(users.get(id));
    }

    @Override
    public List<User> findAll() {
        return new ArrayList<>(users.values());
    }

    @Override
    public User save(User user) {
        if (user.getId() == null) {
            user.setId(idGenerator.getAndIncrement());
        }

        // 使用工具模块的方法
        if (!StringUtils.isEmpty(user.getName())) {
            user.setName(StringUtils.capitalize(user.getName()));
        }

        users.put(user.getId(), user);
        return user;
    }

    @Override
    public void deleteById(Long id) {
        users.remove(id);
    }
}

// 3. 应用模块 (com.example.app)
// module-info.java
module com.example.app {
    // 依赖服务模块
    requires com.example.service;
    requires com.example.utils;

    // 如果需要使用反射访问,需要opens声明
    // opens com.example.app to some.framework;
}

// Application.java
package com.example.app;

import com.example.service.User;
import com.example.service.UserService;
import com.example.service.impl.UserServiceImpl;
import com.example.utils.StringUtils;

public class Application {

    public static void main(String[] args) {
        System.out.println("=== 模块化应用演示 ===");

        // 创建服务实例
        UserService userService = new UserServiceImpl();

        // 1. 查询所有用户
        System.out.println("\n1. 所有用户:");
        userService.findAll().forEach(System.out::println);

        // 2. 添加新用户
        System.out.println("\n2. 添加新用户:");
        User newUser = new User(null, "王五", "wangwu@example.com");
        User savedUser = userService.save(newUser);
        System.out.println("保存的用户: " + savedUser);

        // 3. 查询特定用户
        System.out.println("\n3. 查询用户:");
        userService.findById(1L).ifPresentOrElse(
            user -> System.out.println("找到用户: " + user),
            () -> System.out.println("用户不存在")
        );

        // 4. 使用工具类
        System.out.println("\n4. 字符串工具演示:");
        String text = "hello world";
        System.out.println("原文: " + text);
        System.out.println("首字母大写: " + StringUtils.capitalize(text));
        System.out.println("反转: " + StringUtils.reverse(text));

        // 5. 删除用户
        System.out.println("\n5. 删除用户:");
        userService.deleteById(2L);
        System.out.println("删除后的用户列表:");
        userService.findAll().forEach(System.out::println);
    }
}

🆕 其他重要新特性

🎯 接口默认方法和静态方法

💻 接口增强特性

🎯 示例10:接口新特性

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

// 增强的接口定义
public interface EnhancedCollection<T> {

    // 抽象方法
    List<T> getItems();

    // 默认方法 - 提供默认实现
    default int size() {
        return getItems().size();
    }

    default boolean isEmpty() {
        return getItems().isEmpty();
    }

    default void forEach(java.util.function.Consumer<? super T> action) {
        getItems().forEach(action);
    }

    default List<T> filter(Predicate<T> predicate) {
        return getItems().stream()
            .filter(predicate)
            .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
    }

    // 静态方法 - 工具方法
    static <T> EnhancedCollection<T> of(T... items) {
        return new SimpleEnhancedCollection<>(Arrays.asList(items));
    }

    static <T> EnhancedCollection<T> empty() {
        return new SimpleEnhancedCollection<>(Collections.emptyList());
    }

    // 私有方法 (Java 9+) - 辅助默认方法
    private void logOperation(String operation) {
        System.out.println("执行操作: " + operation);
    }
}

// 简单实现
class SimpleEnhancedCollection<T> implements EnhancedCollection<T> {
    private final List<T> items;

    public SimpleEnhancedCollection(List<T> items) {
        this.items = new ArrayList<>(items);
    }

    @Override
    public List<T> getItems() {
        return items;
    }

    // 可以重写默认方法
    @Override
    public int size() {
        System.out.println("自定义size方法");
        return items.size();
    }
}

// 使用示例
public class InterfaceEnhancementsDemo {

    public static void main(String[] args) {
        System.out.println("=== 接口增强特性演示 ===");

        // 1. 使用静态方法创建集合
        EnhancedCollection<String> fruits = EnhancedCollection.of("苹果", "香蕉", "橙子", "葡萄");

        System.out.println("水果数量: " + fruits.size());
        System.out.println("是否为空: " + fruits.isEmpty());

        // 2. 使用默认方法
        System.out.println("\n所有水果:");
        fruits.forEach(fruit -> System.out.println("- " + fruit));

        // 3. 使用过滤功能
        List<String> filteredFruits = fruits.filter(fruit -> fruit.contains("果"));
        System.out.println("\n包含'果'的水果: " + filteredFruits);

        // 4. 空集合
        EnhancedCollection<String> empty = EnhancedCollection.empty();
        System.out.println("\n空集合大小: " + empty.size());
    }
}

🔧 var关键字(Java 10+)

💻 局部变量类型推断

🎯 示例11:var关键字使用

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

public class VarKeywordDemo {

    public static void main(String[] args) {
        System.out.println("=== var关键字演示 ===");

        // 1. 基本类型推断
        System.out.println("\n1. 基本类型推断:");
        var number = 42;                    // int
        var text = "Hello World";           // String
        var decimal = 3.14;                 // double
        var flag = true;                    // boolean

        System.out.println("number类型: " + ((Object)number).getClass().getSimpleName());
        System.out.println("text类型: " + text.getClass().getSimpleName());
        System.out.println("decimal类型: " + ((Object)decimal).getClass().getSimpleName());
        System.out.println("flag类型: " + ((Object)flag).getClass().getSimpleName());

        // 2. 集合类型推断
        System.out.println("\n2. 集合类型推断:");
        var list = new ArrayList<String>();
        var map = new HashMap<String, Integer>();
        var set = new HashSet<String>();

        list.add("Java");
        list.add("Python");
        map.put("Java", 25);
        map.put("Python", 30);
        set.add("编程语言");

        System.out.println("list: " + list);
        System.out.println("map: " + map);
        System.out.println("set: " + set);

        // 3. 复杂表达式类型推断
        System.out.println("\n3. 复杂表达式:");
        var filteredList = list.stream()
            .filter(lang -> lang.startsWith("J"))
            .collect(Collectors.toList());

        var upperCaseList = list.stream()
            .map(String::toUpperCase)
            .collect(Collectors.toList());

        System.out.println("过滤后: " + filteredList);
        System.out.println("大写后: " + upperCaseList);

        // 4. 循环中使用var
        System.out.println("\n4. 循环中使用var:");
        var numbers = Arrays.asList(1, 2, 3, 4, 5);

        for (var num : numbers) {
            System.out.print(num + " ");
        }
        System.out.println();

        // 5. var的限制
        System.out.println("\n5. var使用注意事项:");

        // ✅ 正确使用
        var validExample = "这是有效的";
        var anotherValid = new ArrayList<String>();

        // ❌ 错误使用(这些会编译错误)
        // var invalid;                    // 必须初始化
        // var nullValue = null;           // 不能推断null
        // var lambda = x -> x * 2;        // 不能推断lambda
        // var array = {1, 2, 3};          // 不能推断数组字面量

        System.out.println("var使用建议:");
        System.out.println("- 在类型明显时使用,提高代码简洁性");
        System.out.println("- 避免在类型不明确时使用,保持代码可读性");
        System.out.println("- 主要用于局部变量,不能用于字段、方法参数或返回类型");
    }
}

🔄 Switch表达式(Java 12+)

💻 增强的Switch语法

🎯 示例12:Switch表达式

public class SwitchExpressionDemo {

    enum Day {
        MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
    }

    enum Season {
        SPRING, SUMMER, AUTUMN, WINTER
    }

    public static void main(String[] args) {
        System.out.println("=== Switch表达式演示 ===");

        // 1. 传统switch vs 新switch表达式
        System.out.println("\n1. 语法对比:");
        Day today = Day.FRIDAY;

        // 传统switch语句
        String dayType1;
        switch (today) {
            case MONDAY:
            case TUESDAY:
            case WEDNESDAY:
            case THURSDAY:
            case FRIDAY:
                dayType1 = "工作日";
                break;
            case SATURDAY:
            case SUNDAY:
                dayType1 = "周末";
                break;
            default:
                dayType1 = "未知";
        }
        System.out.println("传统switch: " + dayType1);

        // 新switch表达式
        String dayType2 = switch (today) {
            case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "工作日";
            case SATURDAY, SUNDAY -> "周末";
        };
        System.out.println("新switch表达式: " + dayType2);

        // 2. 带yield的switch表达式
        System.out.println("\n2. 使用yield:");
        String description = switch (today) {
            case MONDAY -> "周一,新的开始";
            case FRIDAY -> "周五,即将周末";
            case SATURDAY, SUNDAY -> {
                String weekend = "周末";
                yield weekend + ",休息时间";
            }
            default -> {
                yield "普通的" + today.name().toLowerCase();
            }
        };
        System.out.println("描述: " + description);

        // 3. 实际应用示例
        System.out.println("\n3. 实际应用:");
        demonstrateCalculator();
        demonstrateSeasonInfo();
    }

    // 计算器示例
    public static void demonstrateCalculator() {
        System.out.println("计算器示例:");

        double result = calculate(10, 5, "+");
        System.out.println("10 + 5 = " + result);

        result = calculate(10, 5, "*");
        System.out.println("10 * 5 = " + result);

        result = calculate(10, 0, "/");
        System.out.println("10 / 0 = " + result);
    }

    public static double calculate(double a, double b, String operator) {
        return switch (operator) {
            case "+" -> a + b;
            case "-" -> a - b;
            case "*" -> a * b;
            case "/" -> {
                if (b == 0) {
                    System.out.println("警告: 除数不能为0");
                    yield Double.NaN;
                }
                yield a / b;
            }
            case "%" -> a % b;
            default -> {
                System.out.println("不支持的操作符: " + operator);
                yield Double.NaN;
            }
        };
    }

    // 季节信息示例
    public static void demonstrateSeasonInfo() {
        System.out.println("\n季节信息:");

        for (Season season : Season.values()) {
            String info = getSeasonInfo(season);
            System.out.println(season + ": " + info);
        }
    }

    public static String getSeasonInfo(Season season) {
        return switch (season) {
            case SPRING -> "春天,万物复苏,气温回暖";
            case SUMMER -> "夏天,炎热多雨,适合游泳";
            case AUTUMN -> "秋天,天高气爽,收获季节";
            case WINTER -> "冬天,寒冷干燥,注意保暖";
        };
    }
}

🎯 综合实战练习

📊 练习1:函数式编程数据处理器 ⭐⭐⭐⭐

📝 练习描述

使用Lambda表达式和Stream API构建一个数据处理系统,支持复杂的数据查询、统计和转换操作。

🎯 学习目标
  • 熟练运用Lambda表达式
  • 掌握Stream API的高级用法
  • 理解函数式编程思想
  • 学会设计流畅的API
📋 具体要求

基础要求:

  1. 支持多种数据源(文件、数据库、API)
  2. 提供丰富的过滤和转换操作
  3. 实现数据统计和聚合功能
  4. 支持自定义处理函数

进阶要求:
5. 支持并行处理提升性能
6. 实现数据缓存机制
7. 提供数据验证和清洗功能
8. 支持多种输出格式

💡 实现提示
public class DataProcessor<T> {
    private final Stream<T> dataStream;

    public static <T> DataProcessor<T> of(Collection<T> data) {
        return new DataProcessor<>(data.stream());
    }

    public <R> DataProcessor<R> map(Function<T, R> mapper) {
        return new DataProcessor<>(dataStream.map(mapper));
    }

    public DataProcessor<T> filter(Predicate<T> predicate) {
        return new DataProcessor<>(dataStream.filter(predicate));
    }

    public <K> Map<K, List<T>> groupBy(Function<T, K> classifier) {
        return dataStream.collect(Collectors.groupingBy(classifier));
    }
}

⏰ 练习2:现代化日期时间管理系统 ⭐⭐⭐⭐

📝 练习描述

使用新的日期时间API构建一个完整的时间管理系统,支持多时区、定时任务和时间计算。

🎯 学习目标
  • 掌握新日期时间API的使用
  • 理解时区处理机制
  • 学会时间间隔计算
  • 掌握日期格式化和解析
📋 具体要求

基础要求:

  1. 支持多时区时间显示和转换
  2. 实现定时任务调度功能
  3. 提供时间间隔计算工具
  4. 支持多种日期格式

进阶要求:
5. 实现工作日计算(排除节假日)
6. 支持重复事件的时间计算
7. 提供时间统计和分析功能
8. 支持时间数据的导入导出

🔧 练习3:Optional最佳实践重构 ⭐⭐⭐

📝 练习描述

将传统的null检查代码重构为使用Optional的现代化代码,提升代码的安全性和可读性。

🎯 学习目标
  • 掌握Optional的正确使用方式
  • 学会重构遗留代码
  • 理解函数式编程的优势
  • 提升代码质量
📋 具体要求

基础要求:

  1. 识别和重构null检查代码
  2. 使用Optional链式操作
  3. 实现安全的数据访问
  4. 提供默认值处理机制

进阶要求:
5. 设计Optional友好的API
6. 实现复杂的条件逻辑
7. 优化性能和内存使用
8. 编写完整的测试用例

✅ 完成标准

🎯 基础完成标准
  • 正确使用Lambda表达式和方法引用
  • 熟练运用Stream API进行数据处理
  • 掌握新日期时间API的核心功能
  • 理解Optional的使用场景和最佳实践
  • 代码风格符合现代Java规范
🚀 进阶完成标准
  • 能够设计函数式风格的API
  • 性能优化合理,充分利用并行流
  • 错误处理优雅,使用Optional避免NPE
  • 代码可读性高,充分利用新特性简化逻辑
  • 通过完整的单元测试验证
🏆 专家级标准
  • 深入理解函数式编程思想
  • 能够在实际项目中推广新特性使用
  • 设计出优雅且高效的解决方案
  • 具备重构遗留代码的能力
  • 能够指导团队使用现代Java特性

📝 本章小结

🎯 核心知识点回顾

🔗 Lambda表达式与函数式编程
  • ✅ 掌握Lambda表达式的语法和使用场景
  • ✅ 理解函数式接口和方法引用
  • ✅ 学会函数组合和高阶函数
  • ✅ 熟练使用内置函数式接口
🌊 Stream API
  • ✅ 掌握Stream的创建和基本操作
  • ✅ 熟练使用中间操作和终端操作
  • ✅ 理解并行流的使用和性能优化
  • ✅ 掌握复杂的数据处理和统计操作
⏰ 新日期时间API
  • ✅ 掌握LocalDate、LocalTime、LocalDateTime的使用
  • ✅ 理解时区处理和ZonedDateTime
  • ✅ 熟练进行日期计算和格式化
  • ✅ 掌握Period和Duration的时间间隔计算
🔧 Optional类
  • ✅ 理解Optional的设计目的和使用场景
  • ✅ 掌握Optional的创建和基本操作
  • ✅ 熟练使用map、flatMap、filter等方法
  • ✅ 学会Optional与Stream的结合使用
📦 模块化系统
  • ✅ 理解模块化的概念和优势
  • ✅ 掌握module-info.java的编写
  • ✅ 学会模块间的依赖管理
  • ✅ 了解模块化项目的构建和部署
🆕 其他新特性
  • ✅ 掌握接口的默认方法和静态方法
  • ✅ 理解var关键字的使用和限制
  • ✅ 熟练使用Switch表达式
  • ✅ 了解Java版本演进和新特性趋势

📈 学习成果检验

🎯 自我检测清单
  • 能够使用Lambda表达式简化代码
  • 熟练运用Stream API处理集合数据
  • 掌握新日期时间API替代传统Date类
  • 正确使用Optional避免空指针异常
  • 理解模块化系统的基本概念
  • 了解Java新版本的重要特性
🚀 进阶学习方向
方向内容推荐资源
🔧 函数式编程深入Vavr库、响应式编程RxJava、Project Reactor
🌊 大数据处理并行计算、分布式处理Apache Spark、Flink
⏰ 时间处理进阶复杂时区、历法系统Joda-Time迁移指南
📦 模块化实践大型项目模块化、OSGiSpring Boot模块化

🗺️ 专栏学习路径图

📈 Java程序员从0到1成长路径
🎯 第一阶段:Java基础入门 (4-6周) - ✅ 已完成
┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│ 1.开发环境   │───▶│ 2.基础语法   │───▶│ 3.面向对象   │───▶│ 4.核心API   │
│   搭建      │    │             │    │   编程基础   │    │             │
│ ✅ 已完成    │    │ ✅ 已完成    │    │ ✅ 已完成    │    │ ✅ 已完成    │
└─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘

🚀 第二阶段:Java进阶技能 (4-6周)
┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│ 1.高级特性   │    │ 2.I/O与网络  │    │ 3.新特性     │    │ 4.工具框架   │
│             │    │   编程      │    │             │    │   入门      │
│ ✅ 已完成    │    │ ✅ 已完成    │    │ ✅ 已完成    │    │ 🎯 下一步    │
└─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘

🎓 第三阶段:企业级开发 (6-8周)
┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│ 1.Spring     │    │ 2.数据库     │    │ 3.Web开发    │    │ 4.微服务     │
│   框架      │    │   技术      │    │             │    │   架构      │
│ 📅 计划中    │    │ 📅 计划中    │    │ 📅 计划中    │    │ 📅 计划中    │
└─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘
📊 第二阶段详细进度
章节主要内容预计时间难度状态
🔧 1.Java高级特性泛型、反射、注解、枚举1-2周⭐⭐⭐⭐✅ 已完成
📁 2.I/O与网络编程文件操作、网络通信、多线程1-2周⭐⭐⭐⭐✅ 已完成
🆕 3.Java新特性Lambda、Stream API、新日期API1周⭐⭐⭐⭐✅ 已完成
🛠️ 4.工具与框架入门Maven/Gradle、JUnit、日志框架1周⭐⭐⭐🎯 下一步
🎯 当前进度
• 第二阶段进度:75% (3/4章节完成)
• 下一步:学习常用工具与框架入门
• 建议:巩固新特性知识,准备学习开发工具链
• 重点:掌握Maven构建工具、JUnit测试框架和日志系统

🎬 下一章预告

🛠️ 第二阶段第4章:常用工具与框架入门

🎯 下章学习内容

  • 🏗️ Maven/Gradle构建工具详解
  • 🧪 JUnit单元测试框架
  • 📝 Log4j/SLF4J日志框架
  • 🔧 开发工具链最佳实践

💡 学习建议

  • 理解现代Java项目的构建流程
  • 掌握自动化测试的重要性
  • 学会使用专业的开发工具
  • 建立良好的开发习惯

🎉 恭喜完成Java新特性的学习!

你已经掌握了现代Java开发的核心特性,
包括函数式编程、Stream API、新日期时间API等重要内容,
这些技能将大大提升你的编程效率和代码质量!

继续保持学习的热情,向着Java专家的目标前进! 🚀


📧 有问题?欢迎在评论区讨论交流!
⭐ 觉得有用?别忘了点赞收藏!
🔄 继续关注,更多精彩内容即将到来!
Java 24新特性深度解析:从优化技巧到高手进阶指南 Java 24作为长期支持版本(LTS),引入了多项核心新特性,显著提升了开发效率和性能。首先,字符串模板(String Templates)提供了更安全、可读的字符串构建方式,自动处理特殊字符转义,防止注入攻击。其次,值对象(Value Objects)作为预览特性,优化了内存使用,特别适合领域驱动设计中的值类型。此外,结构化并发API解决了多线程编程中的资源管理和错误传播难题,简化了错误处理。在性能优化方面,ZGC支持亚毫秒级暂停,向量API(Vector API)充分利用现代CPU的SIMD指令,提升 阅读详情

相关推荐

示波器面板上的隐藏功能:如何利用BW Limit和EXT TRIG提升测量精度

本文深入探讨示波器面板上的隐藏功能BW Limit和EXT TRIG,揭示它们如何提升测量精度。通过带宽限制(BW Limit)有效滤除高频噪声,结合外部触发(EXT TRIG)确保稳定信号捕获,为电子测量提供专业解决方案。特别适用于开关电源、传感器信号等复杂场景的高精度测量需求。

weixin_30300225的博客 518

第二阶段:Java进阶技能①Java高级特性

本章深入讲解Java高级特性,包括泛型编程、反射机制、注解与枚举四大核心技术。通过丰富的代码示例和实际应用场景,帮助开发者掌握类型安全编程、动态编程、元数据处理和常量管理等高级技能,提升代码质量和开发效率

CodingPhilosophy的博客 1924

SystemVerilog实战:AXI Stream协议从零搭建(附完整代码解析)

本文详细介绍了如何使用SystemVerilog从零搭建AXI Stream协议,包括核心信号解析、接口设计、主从设备实现及验证环境构建。通过完整的代码示例和工程实践技巧,帮助开发者掌握AXI Stream在FPGA/ASIC设计中的高效数据传输方法,特别适合视频处理和网络数据传输等应用场景。

weixin_29207439的博客 359

Java进阶之新特性

它的用处就是简化接口只有一个抽象方法时,匿名内部类语法的复杂程度。也就是说,一切的Lambda表达式,其实都可以写成匿名内部类。说到Lambda表达式,我们就要先看下匿名内部类,如下就是一个使用Runnable的匿名内部类,由于匿名内部类的写法有时候显得比较复杂,因此才有了Lambda表达是对其进行简化//匿名内部类,写法:@Override})//lambda表达式写法只有一个抽象方法的接口,该接口的匿名内部类,必须重写且只能重写该方法。

RubyWinner的博客 1128

一文解读DeepSeek训练数据集

本文重点以DeepSeek为例,详细介绍预训练数据集相关内容。大语言模型LLM(如DeepSeek、ChatGPT、文心一言等)的“智慧”源于它们学习的海量数据集。简单来说,数据集就是模型的“知识库”,通常由互联网公开的文本、图片、视频等。这些数据需满足两个特点:规模大和多样性。规模大是指数据量可达千亿级词汇,让模型学习复杂规律;多样性则涵盖多领域(如科技、文学)、多语言、多形式(对话、新闻),帮助模型适应不同场景。例如,训练数据中既有百科知识,也有日常对话,模型才能既解答专业问题,又能闲聊。

u013891230的博客 7080

手把手教你学SOME/IP「3.2.1.发布/订阅行为」

本文详细介绍了SOME/IP协议中的服务发现机制,重点解析了发布/订阅行为的流程。主要内容包括:1)服务发布与Method通信流程,涵盖find/offer报文交互、TTL保活机制及异常处理;2)服务订阅与Event通信流程,包括subscribe/ack报文交互和组播延迟机制;3)特殊场景如快速发送、半周期回复、重置订阅等机制。通过邮局订阅报纸的类比,帮助理解服务发现的核心原理,并强调流程图对于问题定位的重要性。文章为SOME/IP协议的工程实现提供了实用指导。

nihaoljq2010的博客 1220

第三节 韩顺平 面向对象Java进阶 第二阶段

而且不用通过类名或者对象名来显式调用,而是在加载类或者创建对象时被隐式调用。

2201_75649224的博客 1400

【MATLAB】通过计算曲率和曲率变化率来实现对曲线波浪程度

这段代码将计算给定曲线的曲率,并与给定阈值进行比较以检测拐角。函数是MATLAB中一个常用的函数,可以用于计算曲线在每个点处的曲率。它基于一种被称为“local least squares fitting” 的方法,通过拟合每个点周围的一小段曲线来计算曲率。MATLAB中可以使用多种方法实现拐角检测,其中一种方法是基于曲率半径的算法。该算法通过计算曲线上每个点处的曲率半径,找到拐角和弯曲处。是一个可选参数,用于控制拟合曲线的平滑度,取值范围为0到1,越接近1表示曲线越平滑。表示曲线在每个点处的曲率,

Fanjufei的博客 1918

Java进阶攻略:7大技能+12份进阶笔记+面试150题

以下都是阿里大牛韩飞龙推荐的主流技术,当你全部掌握上述的这些技术那么你就已经是P8级别,而且你也已经形成了自己的体系,当更加新潮的技术出来时那么你自己稍微花点时间就能吃透,毕竟那时候你已经不是以前的那个你了,懂底层原理,知道性能特征,以及功能,想要弄懂新的技术那么也不会太吃力。 本文整理了这份值得收藏的Java架构师进阶攻略,包括以下: 7大进阶专题技能 12份Java进阶学习笔记(包括Spring,设计模式,redis,SpringBoot等) 还有150道阿里架构师面试题目 希望...

weixin_46794373的博客 658

一套适合 ABAP 初级和中级开发人员,从入门到提高的 ABAP 学习教程

曾几何时,ABAP 就是 SAP 的代名词。ABAP 这门编程语言造就了 SAP 名噪一时的 R/3 产品,同时也是如今 SAP 旗舰级产品,SAP S/4HANA 底层的实现语言。 ABAP 不仅代表着 SAP 这家公司在企业级管理软件市场辉煌的过去,ABAP 自身也在不断地进化着。SAP 不仅在本地部署(On-Premise)领域继续保持着自己绝对的统治地位,而且在云应用领域(Software-as-a-Service, 简称 SaaS), 也推出了自己的解决方案,比如 SAP S/4HANA Clo

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 5913

【33】软考软件设计师——算法题(二):贪心法与回溯法深度精讲|第4题进阶满分攻略

本文是《软件设计师·50讲通关|从零基础到工程师职称》专栏第33篇,承接第32篇分治法与动态规划,聚焦**下午第4题算法大题进阶核心**,详解贪心法与回溯法两大高频难点算法。全文超4000字深度拆解贪心法核心原理、贪心选择性质、局部最优推全局最优的底层逻辑,厘清贪心算法适用边界与经典误区;深挖回溯法深度优先遍历思想、递归回溯三步流程、可行性剪枝与最优性剪枝两大核心技巧;全覆盖活动选择、零钱兑换、01背包贪心禁区、八皇后、全排列等软考必考经典题型;配套标准化算法框架代码、考场填空模板、剪枝优化实操案例

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 438

Java编程进阶:从入门到精通,掌握核心技能

通过本文的介绍,相信你已经对Java编程的进阶之路有了全面的了解。从基础知识的回顾到高级特性的掌握,从框架和工具的使用到性能优化和安全编程,再到企业级应用开发和未来发展趋势,Java的世界充满了无限的可能性。希望你能继续深入学习和实践,不断提升自己的技术水平,在编程世界中取得更大的成就。对于那些正在学习Java的初学者来说,这个故事无疑是一个巨大的鼓舞和启示。希望每一位Java学习者都能找到适合自己的学习路径,通过不断实践和积累,最终实现自己的职业梦想。

小筱在线博客 1408

SpringBoot实现快速导入EXCEL

MaterialMonitorController.java @Log(title = "物料监测", businessType = BusinessType.IMPORT) @RequiresPermissions("system:materialMonitor:import") @PostMapping("/importData") @ResponseBody ...

LEN程序员的一生 4817

Java面试热点之Java新特性和语言进阶

详细介绍Java语言自Java 8以来的重要新特性,以及如何利用这些特性进行更高效、现代的Java编程,包括函数式编程风格、集合处理、日期时间处理、模块化编程等方面。

Geek_H 1054

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Java初级进阶中高级工程师必备技能

很多人学了javase以为自己学的已经很OK了,但是其实javase里边有很多的知识点是你不知道的,不管你找的是哪里的javase的视频,大多数是不会讲这些东西,而这些东西你平时业务又不会主动去接触,这块属于java的进阶部分,下面我给大家分享下java初级程序员进阶到中高级需要具备的知识技能。 Java的并发编程 当你用计算机工作的时候,你在同时做多样事情。你可以边听音乐边写文档边读取邮...

坐看云起时_雨宣 8473

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

java进阶一 java8的新特性

前言 前面总结了java基础相关的知识点,包含数据类型、修饰符和string、java三大特性、多线程、IO流,异常等,接下来我们更深一步看看。jdk8发布版已经有一段时间的,里面有些新特性值得去学习一下,我们一起来看看吧。 本篇主要讲述是Java中JDK1.8的一些新语法特性使用,主要是Lambda、Stream和LocalDate日期的一些使用讲解。 Lambda Lambda介绍 ...

月下独舞的博客 407

Java进阶之路必备技能

Java技术的学习阶段有三 第1个是java基础,比如对集合类,并发,IO,JVM,内存模型,泛型,异常,反射,等有深入了解。 第2个是全面的互联网技术相关知识,比如redis,mogodb,nginx,代码自动生成,自动部署,并发问题,性能调优,前端流行框架,spring,mybaties深入了解 … java技术的学习阶段有三 第1个是java基础,比如对集合类,并发,io,jvm,内存模型,泛型,异常,反射,等有深入了解。 第2个是全面的互联网技术相关知识,比如redis,mogodb,nginx,代

mt77633的博客 2439

Java进阶(三)

Java进阶部分内容,包含IO流,File类,特殊文件和日志,以及properties集合的使用等内容。

qq_49474843的博客 1329

怎么高效学习Java进阶技能 需要掌握哪些知识

首先是薪资,这个毋庸置疑,初级Java程序员的薪资在4500-6000的一个水平,当然这里边并不包括实习生。高级Java程序员不仅掌握初级程序员的知识体系,同时进行了更深入的学习,对技术的理解不再浮于表面,而是深入研究,比如你要通过框架的使用了解框架的思想,这样在开发一个项目时思路会开阔一些。随着越来越多的人涌入Java开发行列,初级Java程序员的生存环境变的恶劣,不仅求职竞争愈发激烈,企业对求职者的技能要求也在不断提升。其次是专业技能不同。让自己快速掌握高端技能,可以高效率的学习,积累更多实战经验。..

m0_67401055的博客 191

Java程序员如何进阶为架构师?最全技能总结

要求能独立完成分配的模块开发任务1、掌握最基础的数据结构数组、链表、堆、栈、队列、Hash表、二叉树等2、算法经典排序插入排序、冒泡排序、快排(分化交换排序)、直接选择排序、堆排序、合并排序等。3、语言要求基本的开发基础语言掌握,比如面向对象,集合类、网络IO。4、数据库要求能独立设计数据库表,掌握sql,索引等。...

m0_72885838的博客 371

Java程序员的进阶之路:掌握这些技能,让你在职场如鱼得水!

Java程序员的进阶之路,需要不断学习、积累经验。从基础到进阶,从框架到分布式,每一步都要扎实稳健。希望本文介绍的Java程序员进阶之路,能对您的职业发展有所帮助。祝您在职场如鱼得水,前程似锦!

jsdygtang的博客 665

java -进阶之路

今天开始:发布系列博客<<java - 进阶之路>>

m0_74823595的博客 453

Java8新特性:从 Lambda 到 Stream:掌握 Java 函数式编程

Java 8 引入的 Lambda 表达式与 Stream API 已成为现代 Java 开发的标准工具。本文从函数式编程基础讲起,逐步带你掌握 Lambda 的语法、函数式接口的作用,并深入 Stream 的三步流程与实战应用。通过学习本文,你可以写出更简洁、高效、专业的集合操作代码,真正理解“声明式编程”的魅力。 学完后建议对照文末的“自我检测清单”,确认自己是否掌握了核心知识点。

m0_73944572的博客 832

Java 自学路线图之 Java 进阶自学

Java 自学路线图的第二阶段是 Java 语言进阶自学,在自学了第一阶段的 Java 基础自学后,大家对 Java 语言编程有了初步的了解和认识,建议在第一部分自学后整理一下自己的自学思路,思考自己在自学 Java 基础过程中的不足和优势,建议接下来的自学过程尽量弥补自己的不足。黑马程序员 2020 最新版 Java 自学路线图把 Java 语言进阶自学分为九个部分:面向对象进阶,常见 API,异常,集合,IO,多线程,网络编程,Lambda 以及反射。Lambda 和匿名内部类的区别。

m0_74824025的博客 844

Spring AI + GPT-5.5 + Ollama 配置教程:Base URL、超时与流式调用

由于不同 Spring AI、Spring Boot 小版本之间仍可能存在差异,创建项目时应检查 Spring Initializr、Spring AI BOM 和官方兼容矩阵,不要直接复制旧教程中的 Starter 名称和版本号。多人项目最好隔离不同客户端,并在脱敏前提下记录最终 URL、状态码、请求耗时、请求 ID 和模型 ID。Spring AI 接入模型 API,至少要同时确认 Starter、Base URL、请求路径、API Key、模型 ID、连接超时、读取超时和流式客户端这 8 项。

2601_95893075的博客 219
上一篇: 第二阶段:Java进阶技能②Java I/O与网络编程
下一篇: 第二阶段:Java进阶技能④常用工具与框架入门
代码哲学系
博客等级 码龄1年 55粉丝 18原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值