
case1:
java
package com.lkbhua.IO.Test;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class test3 {
public static void main(String[] args) throws IOException {
/*
文本文件中有以下数据:
2-1-9-4-7-8
将文件中的数据进行排序,变成以下的数据:
1-2-4-7-8-9
*/
// 1、读取文件中的数据
// Alt + 回车
FileReader fr = new FileReader(new File("lkb04-File&IOCode\\a.txt"));
// 把每一个数据存储到一个StringBuilder中
StringBuilder sb = new StringBuilder();
int ch;
while ((ch = fr.read()) != -1) {
sb.append((char) ch);
}
fr.close();
//System.out.println(sb);
// 2、排序
String str = sb.toString();
String[] arrStr = str.split("-");
ArrayList<Integer> list = new ArrayList<>();
for (String s : arrStr) {
int i = Integer.parseInt(s);
list.add(i);
}
//System.out.println(list);
Collections.sort(list);
//System.out.println(list);
// 3、写出
FileWriter fw = new FileWriter(new File("lkb04-File&IOCode\\c.txt"));
for (int i = 0; i < list.size(); i++){
if (i == list.size() - 1){
fw.write(list.get(i) + "");
}
else{
fw.write(list.get(i) + "-");
}
}
fw.close();
System.out.println("完毕");
}
}
🧩一**、为什么用 ArrayList?(核心问题!)**
因为字符串不能直接排序,得先变成数字!
想象一下:
- 你手里有 6张卡片 ,上面写着
2、1、9、4、7、8(全是文字,不是数字!) - 你想按大小排好,但 文字不能比大小("10" 比 "2" 大,但文字顺序 "1" 在 "2" 前)
👉 所以必须:
- 把文字 → 转成数字 (
"2" → 2) - 把数字 → 放进一个可扩容的盒子 (
ArrayList) - 用 自动排序的魔法 (
Collections.sort())
为什么不用数组?
- 数组大小固定,你不知道有多少数字(可能1个,可能100个)
ArrayList像 魔法盒子:你放多少数字,它就自动变多大!
💡 生活类比 :
你用 可伸缩的收纳盒 装玩具,比用固定大小的盒子(数组)方便多了!
🔁 二**、循环怎么执行的?(重点!)**
✅ 第一步:读文件 → 拼成字符串
java
while ((ch = fr.read()) != -1) {
sb.append((char) ch); // 把每个字节转成字符,塞进StringBuilder
}
- 像用小扫帚扫地 :
fr.read()从文件开头一个字节一个字节扫 →ch是当前字节(比如50代表2)
sb.append((char) ch)→ 把50转成2,塞进StringBuilder(高效拼接!) - 执行过程 :
2→2-→2-1→2-1-9→ ... →2-1-9-4-7-8
✅ 直到扫到文件末尾(-1),循环结束!
✅ 第二步:分割字符串 → 转数字
java
String[] arrStr = str.split("-"); // "2-1-9" → ["2", "1", "9"]
for (String s : arrStr) {
int i = Integer.parseInt(s); // "2" → 2
list.add(i); // 把2放进ArrayList
}
- 像分珠子 :
split("-")把字符串按-切开 → 得到["2", "1", "9"]
for循环:遍历每个小珠子 →Integer.parseInt把珠子上的文字转成数字 - 执行过程 :
s="2"→i=2→list=[2]
s="1"→i=1→list=[2,1]
s="9"→i=9→list=[2,1,9]
...(最后list=[2,1,9,4,7,8])
✅ 第三步:排序
Collections.sort(list); // 把list变成 [1,2,4,7,8,9]
- 像用自动排序书架 :
Collections.sort()会把list里所有数字 从小到大排好 ,不用你写排序算法!
✅ 结果:[1,2,4,7,8,9]
✅第四步:写回文件
java
for (int i = 0; i < list.size(); i++) {
if (i == list.size() - 1) {
fw.write(list.get(i) + ""); // 最后一个不加"-"
} else {
fw.write(list.get(i) + "-"); // 其他加"-"
}
}
- 像排版写作业 :
i是当前第几个数字,list.size()-1是最后一个位置
✅ 逻辑 :i=0→1→ 写1-i=1→2→ 写2-- ...
i=5(最后)→9→ 写9(不加-)
- 最终输出 :
1-2-4-7-8-9
case2:
java
package com.lkbhua.IO.Test;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class test4 {
public static void main(String[] args) throws IOException {
/*
文本文件中有以下数据:
2-1-9-4-7-8
将文件中的数据进行排序,变成以下的数据:
1-2-4-7-8-9
*/
// 1、读取文件中的数据
// Alt + 回车
FileReader fr = new FileReader(new File("lkb04-File&IOCode\\a.txt"));
// 把每一个数据存储到一个StringBuilder中
StringBuilder sb = new StringBuilder();
int ch;
while ((ch = fr.read()) != -1) {
sb.append((char) ch);
}
fr.close();
//System.out.println(sb);
// 2、排序
Integer[] arr = Arrays.stream(sb.toString()
.split("-"))
.map(Integer::parseInt)
.sorted()
.toArray(Integer[]::new);
// 3、写出
FileWriter fw = new FileWriter(new File("lkb04-File&IOCode\\c.txt"));
String s = Arrays.toString(arr).replace(",", "-");
String result = s.substring(1, s.length() - 1);
fw.write( result);
fw.close();
}
}
🧩 一、为什么用Stream API?(比ArrayList更酷!)
因为Stream是Java 8的"魔法流水线",能一气呵成完成多个操作!
想象一下:
- 你有一条自动分拣流水线(Stream)
- 你把乱糟糟的字符串("2-1-9")扔进去
- 流水线自动完成:
✅ 文字→数字 (map)
✅ 排序 (sorted)
✅ 装箱(toArray) - 最后直接得到排好序的数字数组!
二、为什么比test3好?
- test3:要写循环 + ArrayList + Collections.sort
- test4:一行代码搞定所有步骤(Stream API)
💡 生活类比 :
你以前要自己:
- 拿起卡片 → 2. 转成数字 → 3. 放进盒子 → 4. 按大小排好
现在用自动流水线:- 把卡片扔进入口 → 2. 机器自动完成所有步骤 → 3. 从出口拿排序好的卡片
🔁 三、Stream怎么执行的?(重点!)
java
Integer[] arr = Arrays.stream(sb.toString().split("-"))
.map(Integer::parseInt)
.sorted()
.toArray(Integer[]::new);
✅ Step 1: sb.toString().split("-")
- 输入 :
"2-1-9-4-7-8" - 操作 :按
-分割 →["2", "1", "9", "4", "7", "8"] - 生活类比 :像把一串珍珠项链 ("2-1-9")拆成单颗珍珠
✅ Step 2: .map(Integer::parseInt)
- 操作 :把每颗珍珠(字符串)转成数字
"2" → 2,"1" → 1,"9" → 9...
- 生活类比 :珍珠自动变钻石 (文字→数字) 💡
Integer::parseInt是Java的快捷写法 ,相当于s -> Integer.parseInt(s)
✅ Step 3: .sorted()
- 操作 :自动按大小排序
[2,1,9,4,7,8] → [1,2,4,7,8,9]
- 生活类比 :钻石自动按大小排列(像智能珠宝架!)
✅ Step 4: .toArray(Integer[]::new)
- 操作 :把排序好的钻石装进数组盒子
- 生活类比 :把排序好的钻石装进透明盒子 (
Integer[] arr)
✅ 整个Stream执行过程 :
["2","1","9"]→ 流水线 →[2,1,9]→ 排序 →[1,2,9]→ 装盒 →[1,2,9]
🌟 四、写出部分为什么这么写?(避免多出逗号和方括号)
java
String s = Arrays.toString(arr).replace(",", "-");
String result = s.substring(1, s.length() - 1);
fw.write(result);
❌ 问题:
Arrays.toString(arr) 会输出 [1,2,4,7,8,9]
但我们需要 1-2-4-7-8-9,不能有方括号和逗号!
✅ 解决方案:
-
.replace(",", "-")- 把
","换成"-"→[1-2-4-7-8-9] - 就像把"逗号"改成"横杠"
- 把
-
.substring(1, s.length() - 1)s = "[1-2-4-7-8-9]"substring(1, s.length()-1):- 从第2个字符开始(
1位置) - 到倒数第2个字符结束(
9位置)
- 从第2个字符开始(
- 就像把"方括号"剪掉
- 结果 :
1-2-4-7-8-9
什么是bom头
🤔 一、BOM头到底是什么?
BOM头(Byte Order Mark) 就是文件开头的隐形小字符,像一个"编码身份证",告诉电脑:"我这个文件是UTF-8编码的哦!"
-
它长啥样?
在UTF-8文件中,BOM头是
EF BB BF(十六进制),也就是三个看不见的字符。- 用代码表示:
"\xEF\xBB\xBF" - 用生活语言说:就像你给文件贴了个"UTF-8"的小标签
- 用代码表示:
-
为什么会有它?
Windows记事本保存UTF-8文件时,自动给文件加了这个小标签(它以为这样能帮电脑更好识别编码)。
💡 举个栗子 :
你把"你好"写在纸上,记事本偷偷加了个"UTF-8"小标签在开头,结果你发给朋友,朋友看到"UTF-8你好",以为"UTF-8"是内容的一部分!
❌ 二、BOM头为什么是个"麻烦精"?
BOM头在普通文本文件中没问题 ,但在PHP文件中是个大麻烦!原因有:
-
PHP不认这个标签
PHP会把BOM头当作文件内容,而不是标签。比如:
Php
编辑
1<?php 2echo "Hello"; // 实际输出:BOM头 + "Hello"- 浏览器看到的是:
Hello,但BOM头已经发送了HTTP头!
- 浏览器看到的是:
-
导致"headers already sent"错误
这是PHP最常见的错误之一!
"Headers already sent by (output started at /path/to/file.php:1)"
-
页面布局问题
即使设置了
top: 0,页面也不会紧贴浏览器顶部,因为BOM头占了位置。
💡 生活类比 :
就像你给朋友写信,信封上写了"UTF-8",但信纸开头也写了"UTF-8",朋友收到信,以为"UTF-8"是信的内容,而不是信封信息。
IDEA如何关闭bom头
