# Java基础
# 一、基础类型与变量
- 8种基本类型
int age = 25; // 4字节整数 double price = 9.99; // 双精度浮点 char grade = 'A'; // 单个字符 boolean isOpen = true; // 布尔值 // 其他:byte, short, long, float1
2
3
4
5 - 引用类型
String name = "Java"; // 字符串(不可变) int[] arr = {1, 2, 3}; // 数组 Object obj = new Object(); // 对象1
2
3
# 二、数据结构
# 1. 数组(Array)
// 一维数组定义
int[] nums = new int[3]; // 定长数组(默认初始化为0)
nums[0] = 10; // 索引访问(范围:0 ~ length-1)
int length = nums.length; // 获取长度(属性,不是方法)
// 二维数组定义与访问
int[][] matrix = {{1,2}, {3,4}};
System.out.println(matrix[1][0]); // 输出 3
// 动态扩容(需新建数组)
int[] newNums = Arrays.copyOf(nums, nums.length * 2); // 长度扩展为原数组2倍
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
特点
- 定长:初始化后长度不可变
- 快速随机访问:通过索引访问元素的时间复杂度为 O(1)
- 内存连续:适合缓存优化,但插入/删除效率低
# 2. 集合框架(Collection Framework)
# List(有序可重复)
ArrayList<String> list = new ArrayList<>();
list.add("A"); // 添加元素(尾部追加,时间复杂度 O(1))
list.add(1, "B"); // 在索引1处插入元素(时间复杂度 O(n))
list.get(0); // 获取元素(时间复杂度 O(1))
list.remove(0); // 删除索引0的元素(返回被删除元素,时间复杂度 O(n))
list.remove("B"); // 删除指定元素(返回 boolean)
int size = list.size(); // 获取长度
boolean isEmpty = list.isEmpty(); // 判空
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# Set(无序唯一)
HashSet<Integer> set = new HashSet<>();
set.add(1); // 添加元素(自动去重,时间复杂度 O(1))
set.contains(1); // 存在性检查(时间复杂度 O(1))
set.remove(1); // 删除元素(返回 boolean)
1
2
3
4
2
3
4
# Map(键值对)
HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 1); // 添加键值对(Key唯一,时间复杂度 O(1))
map.get("apple"); // 根据Key获取Value(不存在返回 null)
map.remove("apple"); // 删除键值对(返回被删除的Value)
int size = map.size(); // 键值对数量
boolean hasKey = map.containsKey("apple"); // Key存在性检查
1
2
3
4
5
6
2
3
4
5
6
# 3. 队列(Queue)
- 特点:先进先出(FIFO)
- 常用实现类:
LinkedList:普通队列PriorityQueue:优先队列(按优先级排序)
Queue<Integer> queue = new LinkedList<>();
queue.add(1); // 添加元素(队列满时抛 IllegalStateException)
queue.offer(2); // 添加元素(队列满时返回 false)
queue.remove(); // 移除队首(队列空时抛 NoSuchElementException)
queue.poll(); // 移除队首(队列空时返回 null)
queue.element(); // 查看队首(不删除,队列空时抛异常)
queue.peek(); // 查看队首(不删除,队列空时返回 null)
1
2
3
4
5
6
7
2
3
4
5
6
7
# 4. 栈(Stack)
- 特点:后进先出(LIFO)
- 注意:Java中
Stack类已过时,推荐用Deque接口实现栈
Deque<Integer> stack = new LinkedList<>();
stack.push(1); // 入栈(头部插入,时间复杂度 O(1))
int top = stack.pop(); // 出栈(头部删除,栈空时抛 NoSuchElementException)
stack.peek(); // 查看栈顶(不删除)
1
2
3
4
2
3
4
# 5. 优先队列(PriorityQueue)
- 特点:元素按自然顺序或自定义 Comparator 排序
- 底层实现:堆结构(默认小顶堆)
// 自然排序(小顶堆)
Queue<Integer> pq = new PriorityQueue<>();
pq.offer(3); pq.offer(1); pq.offer(2);
pq.poll(); // 返回1(最小元素)
// 自定义排序(大顶堆)
Queue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
maxHeap.offer(1); maxHeap.offer(3);
maxHeap.poll(); // 返回3
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 6. LinkedList(双向链表)
- 双重身份:既是
List,也是Deque(双端队列) - 特点:插入/删除效率高(时间复杂度 O(1)),随机访问效率低(时间复杂度 O(n))
LinkedList<String> list = new LinkedList<>();
// 作为List使用
list.add("A"); // 尾部插入
list.get(0); // 获取元素
// 作为队列使用
list.offerLast("B"); // 尾部插入(等效于 addLast)
list.pollFirst(); // 头部删除(等效于 removeFirst)
// 作为栈使用
list.push("C"); // 头部插入(等效于 addFirst)
list.pop(); // 头部删除(等效于 removeFirst)
// 其他方法
list.addFirst("X"); // 头部插入
list.addLast("Y"); // 尾部插入
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 7. 字符串操作
# String 基础操作
String s = "Hello";
int len = s.length(); // 长度(注意:空字符串长度为0)
char c = s.charAt(1); // 获取字符(索引1 → 'e')
String sub = s.substring(0, 2); // 截取子串(左闭右开 → "He")
String[] parts = s.split("l"); // 分割为数组 → ["He", "", "o"]
String newStr = s.replace('l', 'x'); // 替换 → "Hexxo"
1
2
3
4
5
6
2
3
4
5
6
# StringBuilder(高效字符串操作)
StringBuilder sb = new StringBuilder(); // 默认容量16
sb.append("Hello"); // 追加内容(支持链式调用)
sb.insert(5, " World"); // 在索引5处插入
sb.delete(5, 11); // 删除索引5到10的内容
sb.replace(0, 5, "Hi"); // 替换索引0到4的内容为"Hi"
sb.reverse(); // 反转字符串
String result = sb.toString(); // 转换为String
1
2
3
4
5
6
7
2
3
4
5
6
7
| 操作 | String | StringBuilder |
|---|---|---|
| 字符串拼接 | 每次操作生成新对象(内存开销大) | 直接修改原对象(内存高效) |
| 插入/删除 | 需借助 substring 和 concat(效率低) | 直接操作(时间复杂度 O(n)) |
| 线程安全 | 是(不可变) | 否(需线程安全时使用 StringBuffer) |
# 8. 数据结构对比与应用场景
| 数据结构 | 特点 | 典型场景 |
|---|---|---|
ArrayList | 动态数组,随机访问快(O(1)) | 频繁按索引访问元素(如查询、遍历) |
LinkedList | 链表,插入/删除快(O(1)) | 高频头尾操作(如队列、栈) |
ArrayDeque | 双端队列,性能优于 LinkedList | 高并发场景下的栈/队列(非线程安全) |
PriorityQueue | 按优先级出队(堆结构) | 任务调度(如处理最高优先级任务) |
HashSet | 无序唯一集合(哈希表实现) | 快速去重、存在性检查 |
HashMap | 键值对存储(哈希表实现,O(1)查找) | 缓存、快速查找(如词频统计) |
# 9.代码实战模板
# 用队列实现BFS(广度优先搜索)
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
Node node = queue.poll();
// 处理当前节点
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 用栈实现DFS(深度优先搜索)
Deque<Node> stack = new LinkedList<>();
stack.push(root);
while (!stack.isEmpty()) {
Node node = stack.pop();
// 处理当前节点
if (node.right != null) stack.push(node.right); // 右子节点先入栈
if (node.left != null) stack.push(node.left);
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 优先队列处理Top K问题
// 找出数组中前K大的元素
int[] nums = {3,1,5,4,2};
int k = 3;
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int num : nums) {
pq.offer(num);
if (pq.size() > k) pq.poll(); // 保持队列大小为K
}
// 最终pq中保留的是最大的K个元素
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 三、高频工具类
# 1. Arrays 类(数组工具)
int[] arr = {3, 1, 2};
// 排序(升序)
Arrays.sort(arr); // arr → [1, 2, 3]
// 二分查找(需先排序)
int index = Arrays.binarySearch(arr, 2); // 返回索引 1
// 数组转字符串
String arrStr = Arrays.toString(arr); // → "[1, 2, 3]"
// 填充数组
Arrays.fill(arr, 0); // arr → [0, 0, 0]
// 数组拷贝
int[] copyArr = Arrays.copyOf(arr, 5); // 新数组长度5,超出部分补0
// 比较数组内容
boolean isEqual = Arrays.equals(arr, new int[]{0, 0, 0}); // → true
// 多维数组转字符串
int[][] matrix = {{1,2}, {3,4}};
System.out.println(Arrays.deepToString(matrix)); // → "[[1, 2], [3, 4]]"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
应用场景
- 数据预处理:排序、填充、拷贝等操作
- 快速查找:通过
binarySearch在有序数组中定位元素 - 调试输出:用
toString或deepToString打印数组内容
# 2. Collections 类(集合工具)
List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 2));
// 排序(默认升序)
Collections.sort(list); // list → [1, 2, 3]
// 反转顺序
Collections.reverse(list); // list → [3, 2, 1]
// 随机打乱顺序
Collections.shuffle(list); // 可能输出 [2, 1, 3]
// 查找极值
int max = Collections.max(list); // → 3
int min = Collections.min(list); // → 1
// 频率统计
int freq = Collections.frequency(list, 2); // → 1
// 替换所有元素
Collections.fill(list, 0); // list → [0, 0, 0]
// 线程安全包装
List<Integer> syncList = Collections.synchronizedList(list);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
应用场景
- 数据处理:排序、反转、打乱等集合操作
- 统计分析:极值查找、频率统计
- 并发安全:通过
synchronizedList实现线程安全集合
# 3. Math 类(数学工具)
// 基本运算
int max = Math.max(10, 20); // → 20
int min = Math.min(5, 3); // → 3
int abs = Math.abs(-5); // → 5
// 指数与对数
double pow = Math.pow(2, 3); // → 8.0
double log = Math.log(Math.E); // → 1.0
// 取整运算
double ceil = Math.ceil(3.1); // → 4.0
double floor = Math.floor(3.9); // → 3.0
long round = Math.round(3.5); // → 4
// 三角函数
double sin = Math.sin(Math.PI / 2); // → 1.0
double degrees = Math.toDegrees(Math.PI); // → 180.0
// 随机数
double random = Math.random(); // 生成 [0.0, 1.0) 的随机数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
应用场景
- 数值计算:最大值、最小值、绝对值
- 科学运算:幂运算、对数、三角函数
- 随机生成:通过
random生成随机值
# 4. 字符串工具操作
# String 类扩展方法
String str = " Java ";
// 去空格与大小写转换
String trimmed = str.trim(); // → "Java"
String lowerCase = str.toLowerCase(); // → " java "
String upperCase = str.toUpperCase(); // → " JAVA "
// 子串操作
boolean startsWith = str.startsWith("Ja"); // → true
boolean endsWith = str.endsWith(" "); // → true
String substring = str.substring(2, 6); // → "Java"
// 分割与拼接
String[] parts = str.split("a"); // → [" J", "v", " "]
String joined = String.join("-", "A", "B", "C"); // → "A-B-C"
// 正则匹配
boolean isMatch = str.matches(".*Java.*"); // → true
String replaced = str.replaceAll("\\s+", ""); // → "Java"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# StringBuilder 对比
| 操作 | String | StringBuilder |
|---|---|---|
| 修改字符串 | 每次操作生成新对象(内存开销大) | 直接修改原对象(内存高效) |
| 线程安全 | 是(不可变) | 否(需线程安全时使用 StringBuffer) |
| 方法链式调用 | 不支持 | 支持(如 sb.append().insert()) |
# 5. 避坑指南
Arrays.asList()的陷阱List<String> fixedList = Arrays.asList("A", "B"); // fixedList.add("C"); → 抛出 UnsupportedOperationException // 解决方案:包装为可修改的 ArrayList List<String> modifiableList = new ArrayList<>(fixedList);1
2
3
4Collections.shuffle()的随机性// 使用固定种子保证可重复性 Collections.shuffle(list, new Random(42));1
2Math.random()的范围控制// 生成 [1, 100] 的随机整数 int randomNum = (int) (Math.random() * 100) + 1;1
2
# 6. 实战代码模板
# 生成随机数组
int[] randomArray = new int[10];
Random rand = new Random();
for (int i = 0; i < randomArray.length; i++) {
randomArray[i] = rand.nextInt(100); // 生成 0~99 的随机数
}
1
2
3
4
5
2
3
4
5
# 统计集合元素频率
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);
Map<Integer, Integer> frequencyMap = new HashMap<>();
for (Integer num : numbers) {
frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);
}
// 输出:{1=1, 2=2, 3=3}
1
2
3
4
5
6
2
3
4
5
6
# 字符串格式化
String formatted = String.format("Name: %s, Age: %d", "Alice", 25);
// → "Name: Alice, Age: 25"
1
2
2
# 四、数据类型转换
# 1. 基本类型 ↔ 包装类
自动装箱/拆箱
int num = 10;
Integer numObj = num; // 自动装箱(int → Integer)
int num2 = numObj; // 自动拆箱(Integer → int)
// 空指针风险示例
Integer nullObj = null;
int num3 = nullObj; // 运行时抛出 NullPointerException
1
2
3
4
5
6
7
2
3
4
5
6
7
手动显式转换
// 基本类型 → 包装类
Double dObj = Double.valueOf(3.14); // 推荐方式(优于 new Double())
Float fObj = 3.14f; // 自动装箱
// 包装类 → 基本类型
double d = dObj.doubleValue(); // 显式调用方法
int i = Integer.parseInt("100"); // String → int(需处理 NumberFormatException)
// 进制转换
String binary = Integer.toBinaryString(10); // 十进制 → 二进制 → "1010"
String hex = Integer.toHexString(255); // 十进制 → 十六进制 → "ff"
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 2. 字符串 ↔ 其他类型
字符串转基本类型/包装类
// 基础转换
int age = Integer.parseInt("25"); // String → int
double price = Double.parseDouble("9.99");
boolean flag = Boolean.parseBoolean("true");
// 处理异常
try {
int invalid = Integer.parseInt("abc"); // 抛出 NumberFormatException
} catch (NumberFormatException e) {
System.out.println("格式错误!");
}
// 包装类转换
Integer num = Integer.valueOf("100"); // String → Integer
Double d = Double.valueOf("3.14");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
基本类型/对象转字符串
// 标准方法
String score = String.valueOf(95.5); // double → String(推荐)
String code = Integer.toString(123); // int → String
// 快速转换(效率低)
String s1 = 123 + ""; // 隐式调用 String.valueOf()
String s2 = new Object().toString(); // 对象默认返回类名@哈希值
// 格式化输出
String formatted = String.format("价格: %.2f", 9.99); // → "价格: 9.99"
String hexStr = String.format("十六进制: %x", 255); // → "十六进制: ff"
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 3. 集合类型转换
数组 ↔ 集合
// 数组 → List(固定大小)
String[] arr = {"a", "b"};
List<String> fixedList = Arrays.asList(arr);
// fixedList.add("c"); → 抛出 UnsupportedOperationException
// 数组 → 可修改的 List
List<String> modifiableList = new ArrayList<>(Arrays.asList(arr));
// List → 数组
String[] newArr = modifiableList.toArray(new String[0]);
// 基本类型数组 → 集合(需装箱)
int[] intArr = {1, 2, 3};
List<Integer> intList = Arrays.stream(intArr).boxed().collect(Collectors.toList());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
集合间转换
// List → Set(去重)
List<String> list = Arrays.asList("a", "a", "b");
Set<String> set = new HashSet<>(list); // → {"a", "b"}
// Set → List
List<String> newList = new ArrayList<>(set);
// Map → Set(获取键/值集合)
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
Set<String> keys = map.keySet(); // 键集合
Collection<Integer> values = map.values(); // 值集合
// 使用 Stream 转换
List<Integer> numbers = Arrays.asList(1, 2, 3);
Set<Double> doubles = numbers.stream()
.map(n -> n * 1.0)
.collect(Collectors.toSet()); // → {1.0, 2.0, 3.0}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 4. 特殊场景转换
# 日期与字符串
// Date → String
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(date); // → "2023-10-25 14:30:00"
// String → Date
try {
Date parsedDate = sdf.parse("2023-10-25 14:30:00");
} catch (ParseException e) {
e.printStackTrace();
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 枚举类型转换
enum Color { RED, GREEN, BLUE }
// String → Enum
Color color = Color.valueOf("RED"); // 需匹配枚举常量名
// Color color2 = Color.valueOf("red"); → 抛出 IllegalArgumentException
// Enum → String
String colorStr = color.name(); // → "RED"
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 5. 避坑指南
自动拆箱空指针
Integer nullObj = null; int num = nullObj; // 运行时抛出 NullPointerException // 解决方案:判空处理 if (nullObj != null) num = nullObj;1
2
3
4数值转换精度丢失
double d = 3.14; int i = (int) d; // → 3(直接截断小数部分) // 正确做法:使用 Math.round() 或明确业务需求1
2
3集合转换的不可变性
List<String> fixedList = Arrays.asList("A", "B"); // fixedList.add("C"); → 抛出 UnsupportedOperationException // 正确做法:new ArrayList<>(fixedList)1
2
3时间格式兼容性
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); // 解析 "2023-10-25" 会失败,格式需严格匹配1
2
# 6. 性能优化建议
避免频繁字符串拼接
// 低效写法 String result = ""; for (int i = 0; i < 1000; i++) result += i; // 高效写法 StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) sb.append(i); String result = sb.toString();1
2
3
4
5
6
7
8预分配集合大小
// 避免 ArrayList 频繁扩容 List<String> list = new ArrayList<>(1000);1
2使用原生数组处理基本类型
// 优先选择 int[] 而非 List<Integer>(减少装箱开销) int[] data = new int[10000];1
2
# 五、标准输入输出
标准输入输出内容涵盖 控制台交互、文件读写、异常处理、性能优化 等核心场景。
# 1. 控制台输入
# 使用 Scanner 类
import java.util.Scanner;
public class ConsoleInput {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入整数: ");
int num = scanner.nextInt(); // 读取整数
scanner.nextLine(); // 清空输入缓冲区(避免换行符残留)
System.out.print("请输入字符串: ");
String str = scanner.nextLine(); // 读取整行字符串
System.out.print("请输入浮点数: ");
double d = scanner.nextDouble();
scanner.close(); // 关闭资源(推荐使用 try-with-resources)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 使用 BufferedReader 类(更高效)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ConsoleInputBuffered {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("请输入内容: ");
String input = reader.readLine(); // 读取整行字符串
// 转换为其他类型(需手动处理异常)
try {
int num = Integer.parseInt(input);
} catch (NumberFormatException e) {
System.out.println("输入格式错误!");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 方法对比
| 特性 | Scanner | BufferedReader |
|---|---|---|
| 性能 | 较慢(适合简单场景) | 更快(适合高频或大数据量输入) |
| 异常处理 | 自动处理输入不匹配异常 | 需手动捕获 IOException |
| 功能 | 支持直接解析多种数据类型 | 仅读取字符串,需手动转换 |
| 缓冲区管理 | 自动处理换行符 | 需手动处理换行符 |
# 2. 控制台输出
# 基础输出
System.out.println("Hello World"); // 输出并换行
System.out.print("Hello"); // 输出不换行
System.out.printf("姓名: %s, 年龄: %d", "Alice", 25); // 格式化输出
1
2
3
2
3
# 格式化输出语法
| 占位符 | 说明 | 示例 |
|---|---|---|
%d | 整数 | System.out.printf("%d", 10); |
%f | 浮点数 | System.out.printf("%.2f", 3.1415); → 3.14 |
%s | 字符串 | System.out.printf("%s", "Java"); |
%n | 换行符(跨平台兼容) | System.out.printf("Line1%nLine2"); |
%b | 布尔值 | System.out.printf("%b", true); |
# 3. 文件读写
# 写入文件(FileWriter 和 BufferedWriter)
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriteExample {
public static void main(String[] args) {
// 使用 try-with-resources 自动关闭资源
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
writer.write("第一行内容");
writer.newLine(); // 写入换行符(跨平台兼容)
writer.write("第二行内容");
} catch (IOException e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 读取文件(BufferedReader)
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class FileReadExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) {
String line;
while ((line = reader.readLine()) != null) { // 逐行读取
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 二进制文件读写(FileInputStream/FileOutputStream)
// 写入二进制文件
try (FileOutputStream fos = new FileOutputStream("data.bin")) {
byte[] data = {0x48, 0x65, 0x6C, 0x6C, 0x6F}; // "Hello" 的 ASCII 码
fos.write(data);
}
// 读取二进制文件
try (FileInputStream fis = new FileInputStream("data.bin")) {
int byteData;
while ((byteData = fis.read()) != -1) {
System.out.print((char) byteData); // 输出 Hello
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 4. 异常处理与资源管理
# 必须处理 IOException
try {
BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
// 操作代码
} catch (IOException e) {
System.err.println("文件读取失败: " + e.getMessage());
} finally {
if (reader != null) {
try {
reader.close(); // 确保资源关闭
} catch (IOException e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 使用 try-with-resources(自动关闭资源)
// JDK 7+ 支持,实现 AutoCloseable 接口的资源均可自动关闭
try (Scanner scanner = new Scanner(new File("data.txt"))) {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 5. 高级应用场景
# 读取用户密码(控制台隐藏输入)
import java.io.Console;
public class PasswordInput {
public static void main(String[] args) {
Console console = System.console();
if (console == null) {
System.out.println("控制台不可用!");
return;
}
char[] password = console.readPassword("请输入密码: "); // 输入内容不可见
System.out.println("密码长度: " + password.length);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 文件复制(高效缓冲区)
import java.io.*;
public class FileCopy {
public static void main(String[] args) {
try (
InputStream is = new FileInputStream("source.txt");
OutputStream os = new FileOutputStream("target.txt")
) {
byte[] buffer = new byte[1024]; // 1KB 缓冲区
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 6. 避坑指南
未关闭资源导致内存泄漏
// 错误!未关闭 FileWriter FileWriter writer = new FileWriter("data.txt"); writer.write("Hello"); // 正确做法:使用 try-with-resources1
2
3
4输入格式不匹配
// 若用户输入非数字,nextInt() 会抛 InputMismatchException Scanner scanner = new Scanner(System.in); int num = scanner.nextInt(); // 需配合 try-catch 使用1
2
3文件路径问题
// 相对路径依赖运行环境,建议使用绝对路径或明确相对路径基准 File file = new File("src/data/input.txt"); // 相对于项目根目录1
2字符编码问题
// 指定编码读取文件(UTF-8) BufferedReader reader = new BufferedReader( new InputStreamReader(new FileInputStream("data.txt"), StandardCharsets.UTF_8) );1
2
3
4
# 7. 性能优化建议
使用缓冲类提升效率
BufferedReader比直接使用FileReader更快(减少磁盘访问次数)。BufferedWriter同理适用于写操作。
合理设置缓冲区大小
// 根据文件大小调整缓冲区(默认 8KB) BufferedReader reader = new BufferedReader(new FileReader("largefile.txt"), 16384); // 16KB 缓冲区1
2避免频繁的小数据写入
// 低效写法 for (int i = 0; i < 1000; i++) { writer.write("Line " + i); } // 高效写法:批量写入 StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.append("Line ").append(i).append("\n"); } writer.write(sb.toString());1
2
3
4
5
6
7
8
9
10
11