目录
[4. 通过生成器创建:](#4. 通过生成器创建:)
[5. 从文件创建:](#5. 从文件创建:)
[1. filter() - 过滤操作](#1. filter() - 过滤操作)
[2. map() - 映射转换](#2. map() - 映射转换)
[3. sorted() - 默认排序](#3. sorted() - 默认排序)
[4. sorted() - 自定义排序](#4. sorted() - 自定义排序)
[5. distinct() - 去重操作](#5. distinct() - 去重操作)
[6. limit() - 截取前N个元素](#6. limit() - 截取前N个元素)
[7. skip() - 跳过前N个元素](#7. skip() - 跳过前N个元素)
[8. forEach() - 遍历操作](#8. forEach() - 遍历操作)
[9. collect() - 收集结果](#9. collect() - 收集结果)
[10. anyMatch() - 任意匹配](#10. anyMatch() - 任意匹配)
[11. allMatch() - 全部匹配](#11. allMatch() - 全部匹配)
[12. noneMatch() - 无匹配](#12. noneMatch() - 无匹配)
[13. findFirst() - 获取第一个元素](#13. findFirst() - 获取第一个元素)
[14. findAny() - 获取任意元素](#14. findAny() - 获取任意元素)
[15. reduce() - 归约操作](#15. reduce() - 归约操作)
[16. parallelStream() - 并行流](#16. parallelStream() - 并行流)
前言
今天我们来学习Stream流的相关知识。
引入:
今天早上,乐锅用纸叠了一艘小船。当我在陆地上推着它走时,每一步都显得笨拙而缓慢------需要弯腰、用力、再弯腰、再用力。但当我把它轻轻放入溪流中,神奇的事情发生了:小船顺着水流自然滑行,轻盈、流畅,速度远超在陆地上的费力推动。这就是------Stream流
有了Stream流,我们不再关注如何遍历集合 ,而是专注于数据转换的意图 。就像溪流不会关心小船的形状,它只负责将小船从源头带到大海。Stream流接管了底层的迭代逻辑,让我们的代码变得:更简洁、更易读、更高效。
一、Stream流与传统方法的对比
public static void main(String[] args) {
//创建一个集合
Collection<String> data=new ArrayList<>();
data.add("张强");
data.add("赵敏");
data.add("周芷若");
data.add("张傻傻");
data.add("张翠花");
data.add("何东");
}
要求:遍历输出姓张且名字长度为3的集合
1.传统方法,for加if
List<String> newdata=new ArrayList<>();
for(String datas:data){
if(datas.startsWith("张")&&datas.length()==3){
newdata.add(datas);
}
}
System.out.println(newdata);
// 2.stream方法
List<String> newdatas=data.stream().//转换成Stream流
filter(d->d.startsWith("张")).//调用filter api来进行排除
filter(datas->datas.length()==3).
collect(Collectors.toList());//收集成集合
System.out.println(newdatas);
我们可以看到代码换行并翻译以后可读性大大增加 ,
这也是流的初心:方便数据处理与代码玛阅读
二、创建流
1.List创建:
Collection<String> list=new ArrayList<>();
Stream<String> s1=list.stream();
2.Map创建:
//map
Map<String,Integer> s2=new HashMap<>();
//获取map键的流
Stream<String> s3=s2.keySet().stream();
//获取map值的流
Stream<Integer> s4=s2.values().stream();
//获取map值和键的流
Stream<Map.Entry<String,Integer>>s5=s2.entrySet().stream();
3.数组创建:
//获取数组的流
String[] name={"小明","小周","小李","小王"};
// 将数组 name 转换为 Stream 流
Stream<String> s6= Arrays.stream(name);
System.out.println(s6.count());
//直接创建流
Stream<String> s7=Stream.of(name);
Stream<String> s8=Stream.of("小明","小周","小李","小王");
4. 通过生成器创建:
// 4.1 无限流:generate()
//生成随机数无限流
Stream<Double> randomStream = Stream.generate(Math::random);
//生成常量值无限流
Stream<String> constantStream = Stream.generate(() -> "constant");
// 4.2 无限流:iterate()
// 0, 1, 2, 3, 4...
Stream<Long> fibonacciStream = Stream.iterate(0L, n -> n + 1); //这里的L是long类型意思
// 1, 2, 4, 8, 16...
Stream<Long> customIterate = Stream.iterate(1L, n -> n * 2);
// 注意:无限流需要配合limit()使用,否则会无限执行
List<Long> first10Numbers = Stream.iterate(0L, n -> n + 1)
.limit(10)
.collect(Collectors.toList());
5. 从文件创建:
public static void main(String[] args) {
try {
// 读取文件的每一行作为流
Stream<String> linesStream = Files.lines(Paths.get("data.txt"));
// 处理文件内容
linesStream.forEach(System.out::println);
// 注意:文件流需要关闭
linesStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
三、操作流
1. filter() - 过滤操作
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0) // 过滤出偶数
.collect(Collectors.toList());
// 结果: [2, 4, 6, 8, 10]
2. map() - 映射转换
List<String> words = Arrays.asList("java", "python", "c++", "javascript");
List<String> upperCaseWords = words.stream()
.map(String::toUpperCase) // 将每个字符串转换为大写
.collect(Collectors.toList());
// 结果: ["JAVA", "PYTHON", "C++", "JAVASCRIPT"]
3. sorted() - 默认排序
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9, 3);
List<Integer> sortedNumbers = numbers.stream()
.sorted() // 使用自然排序
.collect(Collectors.toList());
// 结果: [1, 2, 3, 5, 8, 9]
4. sorted() - 自定义排序
List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
List<String> sortedByLength = words.stream()
.sorted(Comparator.comparingInt(String::length)) // 按字符串长度排序
.collect(Collectors.toList());
// 结果: ["date", "apple", "cherry", "banana"]
5. distinct() - 去重操作
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3, 4, 4, 4, 4);
List<Integer> uniqueNumbers = numbers.stream()
.distinct() // 去除重复元素
.collect(Collectors.toList());
// 结果: [1, 2, 3, 4]
6. limit() - 截取前N个元素
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> firstThree = numbers.stream()
.limit(3) // 只取前3个元素
.collect(Collectors.toList());
// 结果: [1, 2, 3]
7. skip() - 跳过前N个元素
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> skipFirstThree = numbers.stream()
.skip(3) // 跳过前3个元素
.collect(Collectors.toList());
// 结果: [4, 5, 6, 7, 8, 9, 10]
8. forEach() - 遍历操作
List<String> words = Arrays.asList("hello", "world", "java", "stream");
words.stream()
.forEach(System.out::println); // 对每个元素执行操作
// 输出:
// hello
// world
// java
// stream
9. collect() - 收集结果
List<String> words = Arrays.asList("java", "python", "c++", "javascript");
// 收集到List
List<String> resultList = words.stream()
.filter(w -> w.length() > 3)
.collect(Collectors.toList());
// 收集到Set
Set<String> resultSet = words.stream()
.collect(Collectors.toSet());
// 收集到Map
Map<String, Integer> wordLengthMap = words.stream()
.collect(Collectors.toMap(
Function.identity(),
String::length
));
// 结果: {java=4, python=6, c++=3, javascript=10}
10. anyMatch() - 任意匹配
List<String> words = Arrays.asList("java", "python", "c++", "javascript");
boolean hasLongWord = words.stream()
.anyMatch(w -> w.length() > 10); // 是否存在长度大于10的单词
// 结果: true (因为"javascript"长度为10,不大于10,所以是false)
// 修正:javascript长度是10,不大于10,所以结果是false
11. allMatch() - 全部匹配
List<Integer> numbers = Arrays.asList(2, 4, 6, 8, 10);
boolean allEven = numbers.stream()
.allMatch(n -> n % 2 == 0); // 是否所有数字都是偶数
// 结果: true
12. noneMatch() - 无匹配
List<String> words = Arrays.asList("java", "python", "c++", "javascript");
boolean noEmptyStrings = words.stream()
.noneMatch(String::isEmpty); // 是否没有空字符串
// 结果: true
13. findFirst() - 获取第一个元素
List<String> words = Arrays.asList("java", "python", "c++", "javascript");
Optional<String> firstWord = words.stream()
.filter(w -> w.startsWith("j"))
.findFirst(); // 获取第一个以"j"开头的单词
// 结果: Optional["java"]
14. findAny() - 获取任意元素
List<String> words = Arrays.asList("java", "python", "c++", "javascript");
Optional<String> anyWord = words.stream()
.filter(w -> w.length() > 5)
.findAny(); // 获取任意一个长度大于5的单词
// 结果: 可能是"python"或"javascript"
15. reduce() - 归约操作
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = numbers.stream()
.reduce((a, b) -> a + b); // 求和归约
// 结果: Optional[15]
// 带初始值的reduce
int product = numbers.stream()
.reduce(1, (a, b) -> a * b); // 求乘积,初始值为1
// 结果: 120
16. parallelStream() - 并行流
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.parallelStream() // 使用并行流
.map(n -> {
System.out.println("Processing " + n + " on thread: " + Thread.currentThread().getName());
return n * 2;
})
.reduce(0, Integer::sum);
// 结果: 110 (2+4+6+8+10+12+14+16+18+20)
// 输出会显示在不同线程上处理
四、终结流
//先创建集合
public static void main(String[] args) {
List<Teacher> teachers=new ArrayList<>();
teachers.add(new Teacher("小明",8000.0,18));
teachers.add(new Teacher("小红", 9500.0, 25));
teachers.add(new Teacher("小刚", 7500.0, 22));
teachers.add(new Teacher("小丽", 10000.0, 28));
teachers.add(new Teacher("小强", 8500.0, 30));
1.foreach终结
//foreach终结
teachers.stream().
filter(teacher ->teacher.getAge()>25).
forEach(System.out::println);
2.count终结
long count=teachers.stream().
filter(teacher -> teacher.getPrice()>8000).count();
System.out.println(count);
3.max终结
Optional<Teacher> max=teachers.stream().
max(Comparator.comparingDouble(Teacher::getPrice));
Teacher teacher=max.get();
System.out.println(teacher);
4.Collect收集(!!!)
List<String> list=new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
list.add("张三丰");
list.add("张翠山");
Stream<String>s1=list.stream().filter(s->s.startsWith("张"));
//收集到list集合
List<String> list1=s1.collect(Collectors.toList());
System.out.println(list1);
//收集到set集合
Stream<String> s2=list.stream().filter(s->s.startsWith("张"));
Set<String> list2=s2.collect(Collectors.toSet());
System.out.println(list2);
//收集到数组
Stream<String> s3=list.stream().filter(s -> s.startsWith("张"));
Object[] array=s3.toArray();
System.out.println(Arrays.toString(array));
//收集到map集合
Map<String,Integer> map = teachers.stream().collect(Collectors.toMap(Teacher::getName,Teacher::getAge));
System.out.println(map);
总结
今天的Stream流就到这里结束了。
在这特别感谢牛肉哥关于Stream流api的详细总结,以及平时对我博客的指导和鼓励。
https://liyuanxin.blog.csdn.net/article/details/131773918?fromshare=blogdetail&sharetype=blogdetail&sharerId=131773918&sharerefer=PC&sharesource=2502_94242477&sharefrom=from_link
https://liyuanxin.blog.csdn.net/article/details/131773918?fromshare=blogdetail&sharetype=blogdetail&sharerId=131773918&sharerefer=PC&sharesource=2502_94242477&sharefrom=from_link我是新手程序猿乐锅。本次分享到此结束,感谢大家的观看与支持!如果本期内容对您有帮助,欢迎**点赞、收藏,**您的支持将是我持续创作的最大动力,谢谢!