java 语言的 安装、介绍;语法、流程控制、数组、javaBean 等知识,可以查询上上一个内容
java 语言的 String、StringBuilder、集合、对象和类 进阶、窗体 等知识,可以查阅上一个内容
java 语言的 api、时间类、递归异常、集合
Stream 不是数据结构,而是 对数据源(集合、数组、I/O等)进行高效、声明式处理的操作序列,类似流水线

Stream 操作的三大步骤:数据源 → 中间操作(链式) → 终止操作
创建 Stream
| 方法 | 示例 | 说明 |
|---|---|---|
Collection.stream() | list.stream() | 最常用,从集合获取 |
Arrays.stream() | Arrays.stream(array) | 从数组 |
Stream.of() | Stream.of("a","b","c") | 直接列举元素 |
IntStream.range() | IntStream.range(1, 100) | 生成整数范围(无装箱) |
Stream.iterate() | Stream.iterate(0, n->n+2).limit(10) | 生成无限流,需要限制 |
Stream.generate() | Stream.generate(Math::random).limit(5) | 生成无限流 |
中间操作(惰性,返回新 Stream)
常用组合:filter → map → sorted → limit 或 filter → flatMap → distinct → collect
| 方法 | 用途 | 示例 |
|---|---|---|
| filter | 过滤元素 | .filter(x -> x > 10) |
| map | 转换元素类型或值 | .map(String::length) |
| flatMap | 将每个元素转为流并扁平化(合并) | .flatMap(list -> list.stream()) |
| distinct | 去重(依赖 equals) | .distinct() |
| sorted | 排序 | .sorted() / .sorted(Comparator) |
| limit | 截取前 n 个 | .limit(5) |
| skip | 跳过前 n 个 | .skip(10) |
| peek | 调试查看每个元素(不修改) | .peek(System.out::println) |
| takeWhile (Java 9+) | 取开头满足条件的元素 | .takeWhile(x -> x < 50) |
| dropWhile (Java 9+) | 删除开头满足条件的元素 | .dropWhile(x -> x < 10) |
静态方法
无需主动实例化,直接可以调用的静态工厂方法,它们一般属于构造流的工具方法,用于创建流
| 方法 | 用途 | 示例 |
|---|---|---|
| concat | 合并参数1和参数2两个流为1个流(静态方法) | Stream.concat(Stream a, Stream b) |
Stream.concat(a,b) 创建的流会“接管”原流的数据源,一旦新流被终端操作触发,streamA 和 streamB 都会被消耗关闭,不能再单独操作
终止操作(触发执行,关闭流)
对于 Stream 实例,只要方法返回的不是某种流类型(例如普通对象、基本类型、void),它就是终端操作
| 方法 | 返回 | 说明 |
|---|---|---|
| forEach | void | 遍历每个元素 |
| collect | R(集合/自定义) | 将结果收集到容器,最常用(搭配 Collectors) |
| reduce | Optional / T | 聚合:求和、乘积、拼接等 |
| count | long | 元素个数 |
| anyMatch | boolean | 是否存在任一元素匹配 |
| allMatch | boolean | 是否全部匹配 |
| noneMatch | boolean | 是否全不匹配 |
| findFirst | Optional | 找到第一个元素 |
| findAny | Optional | 找到任意一个(并行流更快) |
| max / min | Optional | 按比较器求最大值/最小值 |
| toArray | Object[] 或指定类型数组 | 转为数组 |
集合获取 Stream 流 操作
使用 Collection 接口中的默认方法(单列集合内置)
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class StreamTest2 {
static void main() {
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
// ArrayList集合 获取 steam 流
list.stream().forEach(i -> System.out.println(i));
HashSet<String> list1 = new HashSet<>();
list1.add("张三");
list1.add("李四");
list1.add("王五");
// HashSet集合 获取 steam 流
list.stream().forEach(i -> System.out.println(i));
HashMap<String, Integer> list2 = new HashMap<>();
list2.put("张三", 100);
list2.put("李四", 100);
list2.put("王五", 80);
// HashMap是双列集合,推荐 entrySet 转为单列后 获取 steam流
Set<Map.Entry<String, Integer>> ent = list2.entrySet();
ent.stream().forEach(i -> System.out.println(i.getKey() + ":" + i.getValue()));
}
}效果展示

数组获取 Stream流 操作
通过 Arrays.stream() 静态方法将数组转换成 stream 流
import java.util.*;
public class StreamTest2 {
static void main() {
int[] list = {1, 2, 3, 4, 5, 6, 7, 8, 9};
Arrays.stream(list).forEach(i -> System.out.println(i));
}
}
效果展示

零散数据获取 Steam流 操作
通过 Stream.of() 传入数据转换成 stream 流
import java.util.*;
import java.util.stream.Stream;
public class StreamTest2 {
static void main() {
Stream<Integer> stream = Stream.of(4, 2, 1, 4, 5, 2);
stream.forEach(System.out::println);
Stream<String> sreeam2 = Stream.of("张三", "李四", "王五");
sreeam2.forEach(System.out::println);
}
}效果展示

当触发终止操作后流将关闭,无法再次执行中间方法
另外,一旦 Stream.concat 创建的新流被关闭,底层的 stream1 和 stream2 就会被关闭,进入 “已操作” 状态,不能再被复用。
因此,建议 一旦流被拼接,只使用 Stream.concat 拼接后的新流。
import java.util.*;
import java.util.stream.Stream;
public class StreamTest2 {
static void main() {
Stream<Integer> s1 = Stream.of(4, 2, 1, 4, 5, 2);
Stream<Integer> s2 = Stream.of(3, 1, 3, 14, 5, 3);
// 合并 s1 和 s2 流
Stream<Integer> s3 = Stream.concat(s1, s2);
s3.forEach(System.out::println);
// 报错:提示流已关闭
s3.distinct().forEach(System.out::println);
// 无法再次调用 s1,因为 s1 已经被消费过了
// s1.forEach(i -> System.out.println(s));
}
}效果展示

错误提示:stream has already been operated upon or closed
Collect 终止收集
通过 collect 方法,传入 Collectors 类,将 stream 流的数据收集并导入到 List 或者 Map 或者 Set 集合中
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamTest2 {
static void main() {
Stream<Integer> s1 = Stream.of(4, 2, 1, 4, 5, 2);
List<Integer> collect = s1.limit(4).skip(1).collect(Collectors.toList());
System.out.println(collect);
}
}效果展示

Collectors.toMap(new Function,new Function) 接收键和值,并得到 map 集合数据
import java.util.ArrayList;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class StreamTest3 {
static void main() {
ArrayList<String> list = new ArrayList<String>();
list.add("张三,22");
list.add("李四,24");
list.add("王五,18");
list.add("老六,24");
list.add("头七,22");
list.add("刘八,13");
Map<String, Integer> collect = list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return Integer.parseInt(s.split(",")[1]) > 18;
}
}).collect(Collectors.toMap(new Function<String, String>() {
@Override
public String apply(String s) {
return s.split(",")[0];
}
}, new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split(",")[1]);
}
}));
System.out.println(collect);
}
}
效果展示

Java 中的 File 类是 java.io 包的一部分,用于表示文件和目录路径名的抽象表示形式。
File类 不是用来读写文件内容的(那要使用 InputStream/OutputStream 等流),而是主要用于文件和目录的创建、删除、重命名、获取属性等元操作。
文件/目录基本判断
| 方法 | 说明 |
|---|---|
boolean exists() | 文件或目录是否存在 |
boolean isFile() | 是否为普通文件 |
boolean isDirectory() | 是否为目录 |
boolean canRead() | 是否可读 |
boolean canWrite() | 是否可写 |
boolean canExecute() | 是否可执行 |
boolean isHidden() | 是否为隐藏文件(依赖于操作系统) |
获取信息
| 方法 | 说明 |
|---|---|
String getName() | 返回文件或目录名,不包含路径 |
String getPath() | 返回构造时传入的路径字符串 |
String getAbsolutePath() | 返回绝对路径字符串 |
String getParent() | 返回父目录路径,可能为 null |
long length() | 文件大小(字节),目录时返回值不确定 |
long lastModified() | 最后修改时间的毫秒值 |
操作文件/目录
| 方法 | 说明 |
|---|---|
boolean createNewFile() | 当且仅当文件不存在时创建一个新的空文件,返回是否成功 |
boolean mkdir() | 创建单级目录 |
boolean mkdirs() | 创建多级目录(包括所有不存在的父目录) |
boolean delete() | 删除文件或空目录。非空目录需递归删除 |
void deleteOnExit() | 在 JVM 退出时删除文件或目录(常用于临时文件) |
boolean renameTo(File dest) | 重命名文件/目录,可能移动文件(取决于操作系统) |
目录遍历
| 方法 | 说明 |
|---|---|
String[] list() | 返回目录下所有文件和目录的名称数组,若为文件或无权限返回 null |
String[] list(FilenameFilter filter) | 带文件名过滤器的名称列表 |
File[] listFiles() | 返回 File 对象数组 |
File[] listFiles(FileFilter filter) | 使用 FileFilter 过滤的 File 数组 |
File[] listFiles(FilenameFilter filter) | 使用 FilenameFilter 过滤的 File 数组 |
路径比较与转换
| 方法 | 说明 |
|---|---|
boolean equals(Object obj) | 比较是否指向同一抽象路径(系统依赖) |
int compareTo(File another) | 按字典顺序比较路径 |
URI toURI() | 将文件路径转换为 file: URI |
Path toPath()(JDK 7+) | 转换为 java.nio.file.Path |
多种 Flie 类关联路径的操作(不使用 Path 类情况)
import java.io.File;
import java.io.IOException;
public class FileTest {
static void main() throws IOException {
// 方式 A:直接给完整路径
File f1 = new File("E:\\smm\\code\\javaWord\\test\\1.txt");
// 方式 B:父路径 + 子路径(推荐,自动处理分隔符)
File parent = new File("E:\\smm\\code\\javaWord");
File f2 = new File(parent, "test\\1.txt");
// 方式 C:字符串父路径 + 子路径
File f3 = new File("E:\\smm\\code\\javaWord", "test\\1.txt");
}
}效果展示

关联路径对应文件
通过 File 类可以创建文件夹、文件,检查文件信息
import java.io.File;
import java.io.IOException;
public class FileTest {
// 存在异常可能 需要抛出异常
static void main() throws IOException {
File dir = new File("E:\\smm\\code\\javaWord\\test");
File file = new File("E:\\smm\\code\\javaWord\\test\\1.txt");
// 创建目录,若路径节点均存在则返回 false
if (dir.mkdirs()) {
System.out.println("目录不存在,已创建。");
}
// 在指定位置创建文件,若原本存在则不处理并返回 false
if (file.createNewFile()) {
System.out.println("文件不存在,已创建。");
}
// 检查状态
System.out.println("是否为文件: " + file.isFile());
System.out.println("大小: " + file.length() + " bytes");
}
}效果展示

通过执行代码后,得到空白文件

通过 new File("").getAbsolutePath() 获取当前项目的绝对路径,如果不指定路径直接创建文件,默认也是当前项目下创建
绝对路径:从盘符开始往下到具体位置文件或文件夹,相对路径:相对于当前项目
import java.io.File;
import java.io.IOException;
public class FileTest {
static void main() throws IOException {
File basedir = new File(new File("").getAbsolutePath());
System.out.println(basedir);
File text = new File("1.txt");
System.out.println(text.getAbsolutePath());
}
}效果展示

获取更多文件数据信息,例如最后更新时间、是否为目录、是否隐藏
package cn.smmcat.test02;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileTest {
static void main() throws IOException {
File basedir = new File(new File("").getAbsolutePath());
System.out.println(basedir.getAbsolutePath());
File text = new File("1.txt");
System.out.println(text.createNewFile()); // 目录是否存在
System.out.println(text.getAbsolutePath()); // 获取此文件绝对路径
System.out.println(text.isFile()); // 判断是否为文件
System.out.println(text.isDirectory()); // 判断是否为目录
System.out.println(text.isHidden()); // 文件是否隐藏
System.out.println(text.length()); // 文件大小(文件夹无法正常显示)
System.out.println(text.getName()); // 获取文件名
// 最后修改时间 并搭配 SimpleDateFormat 进行格式化
String lastUpTime = new SimpleDateFormat("yyyy年M月d日 HH:mm:ss")
.format(new Date(text.lastModified()));
System.out.println(lastUpTime);
}
}
效果展示

通过 File.delete() 可以删除文件或者文件夹,需要注意是:文件夹必须里面没有文件才可以删除,且不走回收站
import java.io.File;
import java.io.IOException;
public class FileTest3 {
static void main() throws IOException {
File file = new File("/temp/2.txt");
File dir = new File("/temp");
// 创建文件夹
dir.mkdirs();
// 创建文件
file.createNewFile();
// 当文件夹存在文件时,无法删除文件夹,返回 false
System.out.println(dir.delete());
// 删除文件,成功返回 true
System.out.println(file.delete());
// 当文件夹中不存在任何文件时候,就可以删除文件夹,返回 true
System.out.println(dir.delete());
}
}效果展示
