Java学习第5天 - 输入输出与字符串处理

学习时间: 4-5小时
学习目标: 掌握Java的I/O操作、文件处理、字符串操作和日期时间处理


📋 详细学习清单

✅ 第一部分:输入输出流(I/O Stream)(90分钟)

1. 控制台输入输出

JavaScript (你熟悉的I/O)

javascript 复制代码
// Node.js 控制台输入
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// 异步输入
rl.question('请输入您的姓名: ', (name) => {
    console.log(`你好, ${name}!`);
    rl.close();
});

// 文件操作
const fs = require('fs');

// 读取文件
fs.readFile('data.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log(data);
});

// 写入文件
fs.writeFile('output.txt', 'Hello World', (err) => {
    if (err) throw err;
    console.log('文件已保存');
});

Java (今天学习的I/O)

java 复制代码
// ConsoleIO.java
import java.util.Scanner;
import java.io.*;

public class ConsoleIO {
    public static void main(String[] args) {
        // 1. 控制台输入 - Scanner类
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("请输入您的姓名: ");
        String name = scanner.nextLine();
        
        System.out.print("请输入您的年龄: ");
        int age = scanner.nextInt();
        
        System.out.print("请输入您的身高(米): ");
        double height = scanner.nextDouble();
        
        // 输出
        System.out.println("=== 个人信息 ===");
        System.out.printf("姓名: %s%n", name);
        System.out.printf("年龄: %d岁%n", age);
        System.out.printf("身高: %.2f米%n", height);
        
        scanner.close();
    }
}

2. 文件输入输出详解

java 复制代码
// FileIOExample.java
import java.io.*;
import java.nio.file.*;
import java.util.List;

public class FileIOExample {
    public static void main(String[] args) {
        // 1. 传统IO方式写入文件
        writeFileTraditional();
        
        // 2. NIO方式写入文件
        writeFileNIO();
        
        // 3. 读取文件内容
        readFileContent();
        
        // 4. 处理二进制文件
        copyBinaryFile();
    }
    
    // 传统IO写入
    public static void writeFileTraditional() {
        try (FileWriter writer = new FileWriter("student_info.txt")) {
            writer.write("学生信息列表\n");
            writer.write("================\n");
            writer.write("张三,20,计算机科学\n");
            writer.write("李四,21,软件工程\n");
            writer.write("王五,19,数据科学\n");
            System.out.println("文件写入完成(传统IO)");
        } catch (IOException e) {
            System.err.println("文件写入失败: " + e.getMessage());
        }
    }
    
    // NIO写入 (Java 7+)
    public static void writeFileNIO() {
        try {
            String content = "这是使用NIO写入的内容\n" +
                           "支持更好的性能和功能\n" +
                           "推荐在新项目中使用";
            
            Path path = Paths.get("nio_example.txt");
            Files.write(path, content.getBytes());
            System.out.println("文件写入完成(NIO)");
        } catch (IOException e) {
            System.err.println("NIO写入失败: " + e.getMessage());
        }
    }
    
    // 读取文件
    public static void readFileContent() {
        System.out.println("\n=== 读取文件内容 ===");
        
        // 方式1:逐行读取
        try (BufferedReader reader = new BufferedReader(new FileReader("student_info.txt"))) {
            String line;
            int lineNumber = 1;
            while ((line = reader.readLine()) != null) {
                System.out.printf("%d: %s%n", lineNumber++, line);
            }
        } catch (IOException e) {
            System.err.println("文件读取失败: " + e.getMessage());
        }
        
        // 方式2:NIO一次性读取所有行
        try {
            Path path = Paths.get("nio_example.txt");
            List<String> lines = Files.readAllLines(path);
            System.out.println("\n=== NIO读取结果 ===");
            lines.forEach(System.out::println);
        } catch (IOException e) {
            System.err.println("NIO读取失败: " + e.getMessage());
        }
    }
    
    // 复制二进制文件
    public static void copyBinaryFile() {
        try (FileInputStream fis = new FileInputStream("source.bin");
             FileOutputStream fos = new FileOutputStream("copy.bin")) {
            
            byte[] buffer = new byte[1024];
            int bytesRead;
            
            while ((bytesRead = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
            System.out.println("二进制文件复制完成");
        } catch (IOException e) {
            System.err.println("文件复制失败: " + e.getMessage());
        }
    }
}

💡 实战练习1:学生成绩管理系统

java 复制代码
// StudentGradeManager.java
import java.io.*;
import java.util.*;

public class StudentGradeManager {
    private static final String FILE_NAME = "grades.txt";
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        while (true) {
            showMenu();
            int choice = scanner.nextInt();
            scanner.nextLine(); // 消费换行符
            
            switch (choice) {
                case 1 -> addStudent(scanner);
                case 2 -> showAllStudents();
                case 3 -> searchStudent(scanner);
                case 4 -> calculateAverage();
                case 5 -> {
                    System.out.println("程序结束");
                    return;
                }
                default -> System.out.println("无效选择,请重新输入");
            }
        }
    }
    
    private static void showMenu() {
        System.out.println("\n=== 学生成绩管理系统 ===");
        System.out.println("1. 添加学生成绩");
        System.out.println("2. 显示所有学生");
        System.out.println("3. 查找学生");
        System.out.println("4. 计算平均分");
        System.out.println("5. 退出");
        System.out.print("请选择操作: ");
    }
    
    private static void addStudent(Scanner scanner) {
        System.out.print("学生姓名: ");
        String name = scanner.nextLine();
        System.out.print("数学成绩: ");
        double math = scanner.nextDouble();
        System.out.print("英语成绩: ");
        double english = scanner.nextDouble();
        System.out.print("Java成绩: ");
        double java = scanner.nextDouble();
        
        try (PrintWriter writer = new PrintWriter(new FileWriter(FILE_NAME, true))) {
            writer.printf("%s,%.1f,%.1f,%.1f%n", name, math, english, java);
            System.out.println("学生信息已保存");
        } catch (IOException e) {
            System.err.println("保存失败: " + e.getMessage());
        }
    }
    
    private static void showAllStudents() {
        System.out.println("\n=== 所有学生成绩 ===");
        System.out.printf("%-10s %-8s %-8s %-8s %-8s%n", 
                         "姓名", "数学", "英语", "Java", "总分");
        System.out.println("".repeat(45));
        
        try (BufferedReader reader = new BufferedReader(new FileReader(FILE_NAME))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(",");
                if (parts.length == 4) {
                    String name = parts[0];
                    double math = Double.parseDouble(parts[1]);
                    double english = Double.parseDouble(parts[2]);
                    double java = Double.parseDouble(parts[3]);
                    double total = math + english + java;
                    
                    System.out.printf("%-10s %-8.1f %-8.1f %-8.1f %-8.1f%n", 
                                     name, math, english, java, total);
                }
            }
        } catch (IOException e) {
            System.err.println("读取失败: " + e.getMessage());
        }
    }
    
    private static void searchStudent(Scanner scanner) {
        System.out.print("输入要查找的学生姓名: ");
        String searchName = scanner.nextLine();
        boolean found = false;
        
        try (BufferedReader reader = new BufferedReader(new FileReader(FILE_NAME))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(",");
                if (parts.length == 4 && parts[0].equals(searchName)) {
                    System.out.println("\n=== 找到学生信息 ===");
                    System.out.println("姓名: " + parts[0]);
                    System.out.println("数学: " + parts[1]);
                    System.out.println("英语: " + parts[2]);
                    System.out.println("Java: " + parts[3]);
                    
                    double total = Double.parseDouble(parts[1]) + 
                                 Double.parseDouble(parts[2]) + 
                                 Double.parseDouble(parts[3]);
                    System.out.printf("总分: %.1f%n", total);
                    System.out.printf("平均分: %.1f%n", total / 3);
                    found = true;
                    break;
                }
            }
            
            if (!found) {
                System.out.println("未找到该学生");
            }
        } catch (IOException e) {
            System.err.println("查找失败: " + e.getMessage());
        }
    }
    
    private static void calculateAverage() {
        double totalMath = 0, totalEnglish = 0, totalJava = 0;
        int count = 0;
        
        try (BufferedReader reader = new BufferedReader(new FileReader(FILE_NAME))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(",");
                if (parts.length == 4) {
                    totalMath += Double.parseDouble(parts[1]);
                    totalEnglish += Double.parseDouble(parts[2]);
                    totalJava += Double.parseDouble(parts[3]);
                    count++;
                }
            }
            
            if (count > 0) {
                System.out.println("\n=== 班级平均分 ===");
                System.out.printf("数学平均分: %.1f%n", totalMath / count);
                System.out.printf("英语平均分: %.1f%n", totalEnglish / count);
                System.out.printf("Java平均分: %.1f%n", totalJava / count);
                System.out.printf("总体平均分: %.1f%n", 
                                (totalMath + totalEnglish + totalJava) / (count * 3));
            } else {
                System.out.println("暂无学生数据");
            }
        } catch (IOException e) {
            System.err.println("计算失败: " + e.getMessage());
        }
    }
}

✅ 第二部分:字符串深度处理 (80分钟)

1. String vs StringBuilder vs StringBuffer

JavaScript (你熟悉的字符串)

javascript 复制代码
// JavaScript 字符串操作
let str = "Hello";
str += " World";  // 创建新字符串
str += "!";       // 再次创建新字符串

// 模板字符串
const name = "张三";
const age = 25;
const message = `你好,${name},你今年${age}岁`;

// 字符串方法
const text = "  Hello World  ";
console.log(text.trim());           // "Hello World"
console.log(text.toUpperCase());    // "  HELLO WORLD  "
console.log(text.split(" "));       // ["", "", "Hello", "World", "", ""]

Java (今天学习的字符串)

java 复制代码
// StringComparison.java
public class StringComparison {
    public static void main(String[] args) {
        // 1. String - 不可变字符串
        demonstrateString();
        
        // 2. StringBuilder - 可变字符串(非线程安全)
        demonstrateStringBuilder();
        
        // 3. StringBuffer - 可变字符串(线程安全)
        demonstrateStringBuffer();
        
        // 4. 性能对比
        performanceComparison();
    }
    
    public static void demonstrateString() {
        System.out.println("=== String演示 ===");
        
        String str1 = "Hello";
        String str2 = " World";
        String result = str1 + str2;  // 创建新的String对象
        
        System.out.println("原始字符串str1: " + str1);  // "Hello" 不变
        System.out.println("拼接结果: " + result);       // "Hello World"
        
        // 字符串常用方法
        String text = "  Java Programming  ";
        System.out.println("原始: '" + text + "'");
        System.out.println("长度: " + text.length());
        System.out.println("去除空格: '" + text.trim() + "'");
        System.out.println("转大写: '" + text.toUpperCase() + "'");
        System.out.println("转小写: '" + text.toLowerCase() + "'");
        System.out.println("是否包含Java: " + text.contains("Java"));
        System.out.println("替换Java为Python: " + text.replace("Java", "Python"));
        
        // 字符串分割
        String csv = "张三,25,北京,工程师";
        String[] parts = csv.split(",");
        System.out.println("分割结果:");
        for (int i = 0; i < parts.length; i++) {
            System.out.printf("  [%d]: %s%n", i, parts[i]);
        }
    }
    
    public static void demonstrateStringBuilder() {
        System.out.println("\n=== StringBuilder演示 ===");
        
        StringBuilder sb = new StringBuilder();
        sb.append("Hello");
        sb.append(" ");
        sb.append("World");
        sb.append("!");
        
        System.out.println("构建的字符串: " + sb.toString());
        
        // StringBuilder常用方法
        sb.insert(5, " Beautiful");  // 在索引5处插入
        System.out.println("插入后: " + sb.toString());
        
        sb.delete(5, 15);            // 删除索引5-15的字符
        System.out.println("删除后: " + sb.toString());
        
        sb.reverse();                // 反转字符串
        System.out.println("反转后: " + sb.toString());
        
        sb.reverse();                // 再次反转回来
        System.out.println("恢复后: " + sb.toString());
        
        // 链式调用
        StringBuilder chain = new StringBuilder()
            .append("Java")
            .append(" is")
            .append(" awesome")
            .append("!");
        System.out.println("链式调用结果: " + chain.toString());
    }
    
    public static void demonstrateStringBuffer() {
        System.out.println("\n=== StringBuffer演示 ===");
        
        StringBuffer buffer = new StringBuffer("Initial");
        buffer.append(" Text");
        buffer.insert(7, " Modified");
        
        System.out.println("StringBuffer结果: " + buffer.toString());
        System.out.println("长度: " + buffer.length());
        System.out.println("容量: " + buffer.capacity());
    }
    
    public static void performanceComparison() {
        System.out.println("\n=== 性能对比 ===");
        
        int iterations = 10000;
        
        // String拼接性能测试
        long startTime = System.currentTimeMillis();
        String str = "";
        for (int i = 0; i < iterations; i++) {
            str += "a";  // 每次都创建新对象
        }
        long stringTime = System.currentTimeMillis() - startTime;
        
        // StringBuilder性能测试
        startTime = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < iterations; i++) {
            sb.append("a");  // 在同一对象上操作
        }
        long sbTime = System.currentTimeMillis() - startTime;
        
        System.out.printf("String拼接%d次耗时: %d毫秒%n", iterations, stringTime);
        System.out.printf("StringBuilder拼接%d次耗时: %d毫秒%n", iterations, sbTime);
        System.out.printf("StringBuilder比String快 %.1f 倍%n", 
                         (double)stringTime / sbTime);
    }
}

2. 字符串格式化与正则表达式

java 复制代码
// StringFormatAndRegex.java
import java.util.regex.*;
import java.text.DecimalFormat;

public class StringFormatAndRegex {
    public static void main(String[] args) {
        // 1. 字符串格式化
        demonstrateStringFormat();
        
        // 2. 正则表达式
        demonstrateRegularExpressions();
        
        // 3. 数字格式化
        demonstrateNumberFormat();
    }
    
    public static void demonstrateStringFormat() {
        System.out.println("=== 字符串格式化 ===");
        
        String name = "张三";
        int age = 25;
        double salary = 12345.678;
        
        // printf风格格式化
        System.out.printf("姓名: %s, 年龄: %d, 薪资: %.2f%n", name, age, salary);
        
        // String.format方法
        String formatted = String.format("员工 %s 今年 %d 岁,月薪 ¥%.2f", 
                                        name, age, salary);
        System.out.println(formatted);
        
        // 其他格式化选项
        System.out.printf("左对齐: %-10s|%n", name);
        System.out.printf("右对齐: %10s|%n", name);
        System.out.printf("补零: %08d%n", 123);
        System.out.printf("科学记数法: %e%n", 123456.789);
        System.out.printf("百分比: %.1f%%%n", 0.85 * 100);
    }
    
    public static void demonstrateRegularExpressions() {
        System.out.println("\n=== 正则表达式 ===");
        
        // 1. 基本匹配
        String email = "[email protected]";
        String emailPattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
        
        boolean isValidEmail = Pattern.matches(emailPattern, email);
        System.out.println("邮箱 " + email + " 有效性: " + isValidEmail);
        
        // 2. 手机号验证
        String[] phones = {"13812345678", "1381234567", "138123456789", "12812345678"};
        String phonePattern = "^1[3-9]\\d{9}$";
        
        System.out.println("\n手机号验证:");
        for (String phone : phones) {
            boolean isValid = Pattern.matches(phonePattern, phone);
            System.out.printf("%s: %s%n", phone, isValid ? "有效" : "无效");
        }
        
        // 3. 查找和替换
        String text = "今天是2023年12月25日,明天是2023年12月26日";
        String datePattern = "(\\d{4})年(\\d{1,2})月(\\d{1,2})日";
        
        Pattern pattern = Pattern.compile(datePattern);
        Matcher matcher = pattern.matcher(text);
        
        System.out.println("\n找到的日期:");
        while (matcher.find()) {
            System.out.printf("完整匹配: %s%n", matcher.group(0));
            System.out.printf("年: %s, 月: %s, 日: %s%n", 
                            matcher.group(1), matcher.group(2), matcher.group(3));
        }
        
        // 替换日期格式
        String replaced = text.replaceAll(datePattern, "$1-$2-$3");
        System.out.println("替换后: " + replaced);
        
        // 4. 分割字符串
        String data = "apple,banana;orange:grape|peach";
        String[] fruits = data.split("[,;:|]");  // 多个分隔符
        System.out.println("\n水果列表:");
        for (String fruit : fruits) {
            System.out.println("- " + fruit);
        }
    }
    
    public static void demonstrateNumberFormat() {
        System.out.println("\n=== 数字格式化 ===");
        
        double number = 123456.789;
        
        // DecimalFormat格式化
        DecimalFormat df1 = new DecimalFormat("#,###.##");
        System.out.println("千分位分隔: " + df1.format(number));
        
        DecimalFormat df2 = new DecimalFormat("¥#,###.00");
        System.out.println("货币格式: " + df2.format(number));
        
        DecimalFormat df3 = new DecimalFormat("000000.000");
        System.out.println("补零格式: " + df3.format(number));
        
        // 百分比格式
        DecimalFormat percent = new DecimalFormat("#.##%");
        System.out.println("百分比: " + percent.format(0.856));
    }
}

💡 实战练习2:文本处理工具

java 复制代码
// TextProcessor.java
import java.util.*;
import java.util.regex.*;

public class TextProcessor {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("=== 文本处理工具 ===");
        System.out.print("请输入一段文本: ");
        String text = scanner.nextLine();
        
        // 1. 基本统计
        analyzeText(text);
        
        // 2. 单词频率统计
        countWordFrequency(text);
        
        // 3. 格式化处理
        formatText(text);
        
        // 4. 敏感词过滤
        filterSensitiveWords(text);
        
        scanner.close();
    }
    
    public static void analyzeText(String text) {
        System.out.println("\n=== 文本统计 ===");
        
        int totalChars = text.length();
        int nonSpaceChars = text.replaceAll("\\s", "").length();
        int words = text.trim().isEmpty() ? 0 : text.trim().split("\\s+").length;
        int lines = text.split("\n").length;
        int sentences = text.split("[.!?]+").length;
        
        System.out.println("总字符数: " + totalChars);
        System.out.println("非空字符数: " + nonSpaceChars);
        System.out.println("单词数: " + words);
        System.out.println("行数: " + lines);
        System.out.println("句子数: " + sentences);
        
        // 字符分布统计
        Map<Character, Integer> charCount = new HashMap<>();
        for (char c : text.toLowerCase().toCharArray()) {
            if (Character.isLetter(c)) {
                charCount.put(c, charCount.getOrDefault(c, 0) + 1);
            }
        }
        
        System.out.println("\n字母频率 (前5位):");
        charCount.entrySet().stream()
            .sorted(Map.Entry.<Character, Integer>comparingByValue().reversed())
            .limit(5)
            .forEach(entry -> 
                System.out.printf("%c: %d次%n", entry.getKey(), entry.getValue()));
    }
    
    public static void countWordFrequency(String text) {
        System.out.println("\n=== 单词频率 ===");
        
        // 提取单词(去除标点符号)
        String[] words = text.toLowerCase()
                            .replaceAll("[^a-zA-Z\\s\\u4e00-\\u9fa5]", "")
                            .split("\\s+");
        
        Map<String, Integer> wordCount = new HashMap<>();
        for (String word : words) {
            if (!word.trim().isEmpty()) {
                wordCount.put(word.trim(), wordCount.getOrDefault(word.trim(), 0) + 1);
            }
        }
        
        System.out.println("单词频率统计 (前10位):");
        wordCount.entrySet().stream()
            .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
            .limit(10)
            .forEach(entry -> 
                System.out.printf("%-10s: %d次%n", entry.getKey(), entry.getValue()));
    }
    
    public static void formatText(String text) {
        System.out.println("\n=== 文本格式化 ===");
        
        // 1. 标准化空格
        String normalized = text.replaceAll("\\s+", " ").trim();
        System.out.println("标准化空格: " + normalized);
        
        // 2. 首字母大写
        String capitalized = Arrays.stream(normalized.split("\\s+"))
            .map(word -> {
                if (word.length() > 0) {
                    return Character.toUpperCase(word.charAt(0)) + 
                           word.substring(1).toLowerCase();
                }
                return word;
            })
            .reduce("", (a, b) -> a.isEmpty() ? b : a + " " + b);
        System.out.println("首字母大写: " + capitalized);
        
        // 3. 驼峰命名
        String camelCase = Arrays.stream(normalized.split("\\s+"))
            .map(word -> Character.toUpperCase(word.charAt(0)) + 
                        word.substring(1).toLowerCase())
            .reduce("", String::concat);
        System.out.println("驼峰命名: " + camelCase);
        
        // 4. 下划线命名
        String snakeCase = normalized.toLowerCase().replaceAll("\\s+", "_");
        System.out.println("下划线命名: " + snakeCase);
    }
    
    public static void filterSensitiveWords(String text) {
        System.out.println("\n=== 敏感词过滤 ===");
        
        // 敏感词列表(示例)
        String[] sensitiveWords = {"坏蛋", "笨蛋", "傻瓜"};
        
        String filtered = text;
        for (String word : sensitiveWords) {
            if (filtered.contains(word)) {
                String replacement = "*".repeat(word.length());
                filtered = filtered.replace(word, replacement);
                System.out.printf("发现敏感词: %s -> %s%n", word, replacement);
            }
        }
        
        System.out.println("过滤后文本: " + filtered);
        
        // 使用正则表达式批量替换
        String regexFiltered = text.replaceAll("(?i)(坏蛋|笨蛋|傻瓜)", "***");
        System.out.println("正则过滤结果: " + regexFiltered);
    }
}

✅ 第三部分:日期时间处理 (50分钟)

1. 新旧API对比

java 复制代码
// DateTimeExample.java
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

public class DateTimeExample {
    public static void main(String[] args) {
        // 1. 新API使用 (Java 8+)
        demonstrateNewDateTimeAPI();
        
        // 2. 日期计算
        demonstrateDateCalculations();
        
        // 3. 日期格式化
        demonstrateDateFormatting();
        
        // 4. 时区处理
        demonstrateTimeZones();
    }
    
    public static void demonstrateNewDateTimeAPI() {
        System.out.println("=== Java 8+ 日期时间API ===");
        
        // 获取当前日期时间
        LocalDate today = LocalDate.now();
        LocalTime now = LocalTime.now();
        LocalDateTime dateTime = LocalDateTime.now();
        Instant instant = Instant.now();
        
        System.out.println("当前日期: " + today);
        System.out.println("当前时间: " + now);
        System.out.println("当前日期时间: " + dateTime);
        System.out.println("时间戳: " + instant);
        
        // 创建特定日期时间
        LocalDate birthday = LocalDate.of(1995, 6, 15);
        LocalTime meeting = LocalTime.of(14, 30, 0);
        LocalDateTime appointment = LocalDateTime.of(2024, 1, 15, 10, 30);
        
        System.out.println("生日: " + birthday);
        System.out.println("会议时间: " + meeting);
        System.out.println("预约时间: " + appointment);
        
        // 解析字符串
        LocalDate parsed1 = LocalDate.parse("2024-01-15");
        LocalDateTime parsed2 = LocalDateTime.parse("2024-01-15T10:30:00");
        
        System.out.println("解析日期: " + parsed1);
        System.out.println("解析日期时间: " + parsed2);
    }
    
    public static void demonstrateDateCalculations() {
        System.out.println("\n=== 日期计算 ===");
        
        LocalDate today = LocalDate.now();
        
        // 日期加减
        LocalDate tomorrow = today.plusDays(1);
        LocalDate nextWeek = today.plusWeeks(1);
        LocalDate nextMonth = today.plusMonths(1);
        LocalDate nextYear = today.plusYears(1);
        
        System.out.println("今天: " + today);
        System.out.println("明天: " + tomorrow);
        System.out.println("下周: " + nextWeek);
        System.out.println("下月: " + nextMonth);
        System.out.println("明年: " + nextYear);
        
        // 日期差计算
        LocalDate startDate = LocalDate.of(2024, 1, 1);
        LocalDate endDate = LocalDate.of(2024, 12, 31);
        
        long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
        long weeksBetween = ChronoUnit.WEEKS.between(startDate, endDate);
        long monthsBetween = ChronoUnit.MONTHS.between(startDate, endDate);
        
        System.out.printf("%s 到 %s:%n", startDate, endDate);
        System.out.printf("相差 %d 天%n", daysBetween);
        System.out.printf("相差 %d 周%n", weeksBetween);
        System.out.printf("相差 %d 月%n", monthsBetween);
        
        // 判断日期关系
        LocalDate date1 = LocalDate.of(2024, 6, 15);
        LocalDate date2 = LocalDate.of(2024, 6, 20);
        
        System.out.printf("%s 在 %s 之前: %b%n", date1, date2, date1.isBefore(date2));
        System.out.printf("%s 在 %s 之后: %b%n", date1, date2, date1.isAfter(date2));
        System.out.printf("今年是闰年: %b%n", today.isLeapYear());
    }
    
    public static void demonstrateDateFormatting() {
        System.out.println("\n=== 日期格式化 ===");
        
        LocalDateTime now = LocalDateTime.now();
        
        // 预定义格式
        System.out.println("ISO格式: " + now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        
        // 自定义格式
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        System.out.println("中文格式: " + now.format(formatter1));
        
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        System.out.println("标准格式: " + now.format(formatter2));
        
        DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a");
        System.out.println("美式格式: " + now.format(formatter3));
        
        // 只格式化日期或时间
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        
        System.out.println("仅日期: " + now.format(dateFormatter));
        System.out.println("仅时间: " + now.format(timeFormatter));
        
        // 解析自定义格式
        String dateString = "2024年1月15日 14:30:00";
        LocalDateTime parsed = LocalDateTime.parse(dateString, formatter1);
        System.out.println("解析结果: " + parsed);
    }
    
    public static void demonstrateTimeZones() {
        System.out.println("\n=== 时区处理 ===");
        
        // 当前时区时间
        ZonedDateTime currentZone = ZonedDateTime.now();
        System.out.println("当前时区: " + currentZone);
        
        // 不同时区的相同时刻
        ZonedDateTime beijing = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        ZonedDateTime tokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
        ZonedDateTime london = ZonedDateTime.now(ZoneId.of("Europe/London"));
        ZonedDateTime newYork = ZonedDateTime.now(ZoneId.of("America/New_York"));
        
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss (zzz)");
        
        System.out.println("北京时间: " + beijing.format(formatter));
        System.out.println("东京时间: " + tokyo.format(formatter));
        System.out.println("伦敦时间: " + london.format(formatter));
        System.out.println("纽约时间: " + newYork.format(formatter));
        
        // 时区转换
        ZonedDateTime beijingMeeting = ZonedDateTime.of(
            2024, 1, 15, 14, 0, 0, 0, 
            ZoneId.of("Asia/Shanghai")
        );
        
        ZonedDateTime newYorkTime = beijingMeeting.withZoneSameInstant(
            ZoneId.of("America/New_York")
        );
        
        System.out.printf("北京时间 %s 对应纽约时间 %s%n", 
                         beijingMeeting.format(formatter),
                         newYorkTime.format(formatter));
    }
}

📚 今日作业与练习

作业1:个人日记系统

创建一个简单的日记系统,要求:

  • 用户可以写入日记(包含日期、心情、内容)
  • 可以按日期查看历史日记
  • 支持关键词搜索日记内容
  • 日记保存到文件中

作业2:文本分析工具

编写程序分析一篇文章:

  • 统计字数、句数、段落数
  • 找出最常用的10个单词
  • 检查文本中的邮箱地址和电话号码
  • 生成文本摘要(截取前100个字符)

作业3:日程管理器

实现简单的日程管理功能:

  • 添加日程(标题、时间、地点、描述)
  • 查看今日/明日/本周日程
  • 日程提醒(距离开始时间的倒计时)
  • 支持日程的修改和删除

🎯 明日预告:第6天

学习内容:

  • 多线程编程基础
  • 线程同步与锁机制
  • 线程池的使用
  • 并发集合类

重点技能:

  • 理解线程概念
  • 掌握synchronized关键字
  • 学会使用ExecutorService
  • 避免常见的并发问题
相关推荐
今天我要乾重生14 分钟前
java基础学习(三十)
java·开发语言·学习
JWASX2 小时前
【RocketMQ 生产者和消费者】- 消费者重平衡(1)
java·rocketmq·重平衡
剽悍一小兔2 小时前
自动化文档生成工具(亲测可运行)
java
程序员皮皮林2 小时前
使用 Java + WebSocket 实现简单实时双人协同 pk 答题
java·websocket
栗然2 小时前
Spring Boot 项目中使用 MyBatis 的 @SelectProvider 注解并解决 SQL 注入的问题
java·后端
im_AMBER2 小时前
java复习 19
java·开发语言
陆少枫2 小时前
JDBC强化关键_009_连接池
java·数据库·mysql
安迪小宝2 小时前
2 geotools入门示例
java·spring boot
Moshow郑锴2 小时前
IDEA高效快捷键指南
java·ide·intellij-idea
小猫咪怎么会有坏心思呢2 小时前
华为OD机考-异常的打卡记录-字符串(JAVA 2025B卷)
java·开发语言·华为od