Map集合复习

掌握HashMap、TreeMap和LinkedHashMap的特点与使用场景

HashMap

  • 基于哈希表实现
  • 无序存储,不保证顺序
  • 允许null键和null值
  • 查找效率高:O(1)

TreeMap

  • 基于红黑树实现
  • 按键的自然顺序或Comparator排序
  • 不允许null键
  • 查找效率:O(log n)

LinkedHashMap

  • 继承自HashMap
  • 维护插入顺序或访问顺序
  • 允许null键和null值
  • 查找效率:O(1)

Map集合使用示例

import java.util.*; public class MapExample { public static void main(String[] args) { // HashMap示例 Map hashMap = new HashMap<>(); hashMap.put("Alice", 25); hashMap.put("Bob", 30); hashMap.put(null, 0); // 允许null键 System.out.println("HashMap: " + hashMap); // TreeMap示例 Map treeMap = new TreeMap<>(); treeMap.put("Charlie", 35); treeMap.put("Alice", 25); treeMap.put("Bob", 30); // treeMap.put(null, 0); // 抛出NullPointerException System.out.println("TreeMap (自然排序): " + treeMap); // LinkedHashMap示例(插入顺序) Map linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("Bob", 30); linkedHashMap.put("Alice", 25); linkedHashMap.put("Charlie", 35); System.out.println("LinkedHashMap (插入顺序): " + linkedHashMap); } }

常见错误

错误: 在TreeMap中使用不可比较的键

原因: 如果键没有实现Comparable接口且没有提供Comparator

解决: 确保键实现Comparable接口或提供Comparator

// 错误示例 Map map = new TreeMap<>(); // Person未实现Comparable // 正确解决方案1:实现Comparable class Person implements Comparable { // 实现compareTo方法 } // 正确解决方案2:提供Comparator Map map = new TreeMap<>(Comparator.comparing(Person::getName));

Collections工具类

掌握集合排序、查找、同步等操作

常用Collections方法

方法 描述 示例
sort() 对List进行排序 Collections.sort(list)
binarySearch() 二分查找已排序列表 Collections.binarySearch(list, key)
reverse() 反转List中元素顺序 Collections.reverse(list)
shuffle() 随机打乱List中元素 Collections.shuffle(list)
synchronizedXxx() 创建同步集合 Collections.synchronizedList(list)

集合排序示例

import java.util.*; public class CollectionsExample { public static void main(String[] args) { List numbers = new ArrayList<>(); numbers.add(5); numbers.add(2); numbers.add(8); numbers.add(1); // 自然排序 Collections.sort(numbers); System.out.println("自然排序: " + numbers); // 自定义排序(降序) Collections.sort(numbers, (a, b) -> b - a); System.out.println("降序排序: " + numbers); // 对象排序 List people = new ArrayList<>(); people.add(new Person("Alice", 25)); people.add(new Person("Bob", 30)); people.add(new Person("Charlie", 22)); // 按年龄排序 Collections.sort(people, Comparator.comparingInt(Person::getAge)); System.out.println("按年龄排序: " + people); // 按姓名排序 Collections.sort(people, Comparator.comparing(Person::getName)); System.out.println("按姓名排序: " + people); } static class Person { String name; int age; Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return name + "(" + age + ")"; } } }

File文件操作

掌握Java文件与目录操作的核心方法

File类核心方法

方法 描述 返回值
exists() 检查文件/目录是否存在 boolean
isFile() 检查是否为文件 boolean
isDirectory() 检查是否为目录 boolean
length() 获取文件大小(字节) long
mkdir() 创建单级目录 boolean
mkdirs() 创建多级目录 boolean
listFiles() 获取目录内容 File[]
delete() 删除文件或目录 boolean

文件操作示例

import java.io.File; import java.io.IOException; public class FileExample { public static void main(String[] args) { // 创建File对象 File file = new File("test.txt"); // 检查文件是否存在 if (!file.exists()) { try { // 创建新文件 if (file.createNewFile()) { System.out.println("文件创建成功: " + file.getName()); } } catch (IOException e) { System.err.println("创建文件失败: " + e.getMessage()); } } // 获取文件信息 System.out.println("文件路径: " + file.getAbsolutePath()); System.out.println("文件大小: " + file.length() + " bytes"); System.out.println("是否可读: " + file.canRead()); System.out.println("是否可写: " + file.canWrite()); // 目录操作 File dir = new File("my_directory"); if (!dir.exists()) { // 创建多级目录 if (dir.mkdirs()) { System.out.println("目录创建成功: " + dir.getName()); } } // 列出目录内容 if (dir.isDirectory()) { System.out.println("目录内容:"); File[] files = dir.listFiles(); if (files != null) { for (File f : files) { System.out.println(f.getName() + (f.isDirectory() ? " [目录]" : " [文件]")); } } } // 删除文件 if (file.delete()) { System.out.println("文件删除成功"); } } }

字节流与字符流

掌握InputStream/OutputStream和Reader/Writer的使用

字节流

  • 操作原始字节数据
  • 核心类:InputStream/OutputStream
  • 适合处理二进制文件
  • 实现类:FileInputStream, ByteArrayInputStream等

字符流

  • 操作字符数据
  • 核心类:Reader/Writer
  • 自动处理字符编码
  • 适合处理文本文件

文件复制示例

import java.io.*; public class StreamExample { // 使用字节流复制文件 public static void copyFileWithByteStream(String source, String dest) throws IOException { try (InputStream in = new FileInputStream(source); OutputStream out = new FileOutputStream(dest)) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } } } // 使用字符流复制文本文件 public static void copyTextFileWithCharStream(String source, String dest) throws IOException { try (Reader reader = new FileReader(source); Writer writer = new FileWriter(dest)) { char[] buffer = new char[4096]; int charsRead; while ((charsRead = reader.read(buffer)) != -1) { writer.write(buffer, 0, charsRead); } } } public static void main(String[] args) { try { // 复制二进制文件(如图片) copyFileWithByteStream("source.jpg", "copy_byte.jpg"); // 复制文本文件 copyTextFileWithCharStream("source.txt", "copy_char.txt"); System.out.println("文件复制成功"); } catch (IOException e) { System.err.println("文件复制失败: " + e.getMessage()); } } }

缓冲流、转换流、打印流

掌握高级I/O流的使用与组合

缓冲流

  • 提高I/O效率
  • BufferedInputStream/BufferedOutputStream
  • BufferedReader/BufferedWriter
  • 特有方法:readLine(), newLine()

转换流

  • 字节流与字符流的桥梁
  • InputStreamReader/OutputStreamWriter
  • 处理字符编码转换

打印流

  • 提供格式化输出
  • PrintStream/PrintWriter
  • 自动调用toString()
  • 不会抛出I/O异常

高级流组合示例

import java.io.*; import java.nio.charset.StandardCharsets; public class AdvancedStreamExample { public static void main(String[] args) { // 读取UTF-8编码文件(使用缓冲和转换流) try (BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream("utf8_file.txt"), StandardCharsets.UTF_8))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } // 写入格式化数据(使用缓冲和打印流) try (PrintWriter writer = new PrintWriter( new BufferedWriter( new OutputStreamWriter( new FileOutputStream("output.txt"), StandardCharsets.UTF_8)))) { writer.println("===== 数据报告 ====="); writer.printf("时间: %tF %n", System.currentTimeMillis()); writer.printf("系统用户: %s %n", System.getProperty("user.name")); writer.printf("内存使用: %.2f MB %n", Runtime.getRuntime().totalMemory() / (1024.0 * 1024)); // 检查错误 if (writer.checkError()) { System.err.println("写入过程中发生错误"); } } catch (IOException e) { e.printStackTrace(); } } }

对象序列化与反序列化

掌握Java对象持久化技术

序列化核心概念

  • Serializable接口:标记接口,表示可序列化
  • transient关键字:标记不序列化的字段
  • serialVersionUID:版本控制标识
  • ObjectOutputStream:序列化对象
  • ObjectInputStream:反序列化对象

序列化示例

import java.io.*; public class SerializationExample { public static void main(String[] args) { // 创建可序列化对象 Person person = new Person("Alice", 30, "alice@example.com"); // 序列化对象到文件 try (ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("person.ser"))) { oos.writeObject(person); System.out.println("对象序列化成功"); } catch (IOException e) { e.printStackTrace(); } // 从文件反序列化对象 try (ObjectInputStream ois = new ObjectInputStream( new FileInputStream("person.ser"))) { Person deserializedPerson = (Person) ois.readObject(); System.out.println("反序列化对象: " + deserializedPerson); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } static class Person implements Serializable { // 显式声明serialVersionUID private static final long serialVersionUID = 1L; private String name; private int age; private transient String email; // 不序列化 public Person(String name, int age, String email) { this.name = name; this.age = age; this.email = email; } @Override public String toString() { return "Person{name='" + name + "', age=" + age + ", email='" + (email != null ? email : "null") + "'}"; } } }

序列化常见错误

错误1: 序列化非Serializable对象

解决: 确保所有序列化对象实现Serializable接口

错误2: serialVersionUID不匹配

解决: 显式声明serialVersionUID保持版本一致

错误3: 序列化后修改类结构

解决: 避免修改已序列化类的结构,或使用兼容性策略

综合测试题

检验Java第二阶段知识掌握情况

题目1:Map集合应用

编写一个程序,统计一段文本中每个单词出现的次数,并按出现次数从高到低排序输出。

要求:

  • 使用HashMap存储单词和出现次数
  • 使用Collections.sort进行排序
  • 忽略大小写(将所有单词转为小写)
  • 过滤掉标点符号

题目2:文件操作与I/O流

实现一个文件加密工具,要求:

  • 使用字节流读取文件
  • 使用简单的异或加密算法(每个字节与密钥异或)
  • 使用缓冲流提高性能
  • 提供加密和解密功能
  • 支持大文件处理(分块处理)

题目3:对象序列化应用

设计一个学生管理系统,要求:

  • 定义Student类(包含学号、姓名、成绩)
  • 实现Serializable接口
  • 提供添加、删除、查询学生功能
  • 将学生列表序列化保存到文件
  • 程序启动时从文件加载学生数据
  • 使用TreeMap按学号排序存储学生

题目4:综合应用

实现一个日志分析工具:

  • 从多个日志文件读取数据(不同编码格式)
  • 使用转换流处理不同编码
  • 提取包含"ERROR"的日志条目
  • 按时间排序所有错误日志
  • 将结果写入HTML格式的报告
  • 使用PrintWriter生成格式化输出