2025.04.09
Stream流
一、Stream流思想及获取Stream流
1.1 Stream流思想
- Stream流的思想是像流水线一样对数据进行一步一步的处理
- Stream流的作用:结合了Lambda表达式,简化集合、数组的操作
- Stream流使用步骤:
- 先得到一条Stream流(流水线),并把数据放上去
- 利用Stream流中的API进行各种操作
- 使用中间方法对流水线上的数据进行操作
- 使用终结方法对流水线线上的数据进行操作
- Stream流中的方法:
- 中间方法:方法调用完毕之后,还可以调用其他方法
- 终结方法:最后一步,调用完毕之后,不能调用其他方法
1.2 Stream流使用方法
- Stream流使用步骤:
- 先得到一条Stream流(流水线),并把数据放上去
- 使用中间方法对流水线上的数据进行操作
- 使用终结方法对流水线线上的数据进行操作
1.2.1 获取Stream流
| 获取方式 |
方法名 |
说明 |
| 单列集合 |
default Stream<E> stream() |
Collection中的默认方法 |
| 双列集合 |
无 |
无法直接使用Stream流 |
| 数组 |
public static<T> Stream<T> stream(T[] array) |
Arrays工具类中的静态方法 |
| 一堆零散数据 |
public static<T> Stream<T> of(T…values) |
Stream接口中的静态方法 |
注意:
- Stream接口中静态方法of的细节:
- 方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组
- 但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当做一个元素放到Stream流中
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| import java.util.*; import java.util.stream.Stream;
public class Main { public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>(); Collections.addAll(list, "A", "B", "C", "D"); Stream<String> stream1 = list.stream(); stream1.forEach(s -> System.out.println(s));
HashMap<String, Integer> map = new HashMap<>(); map.put("A", 1); map.put("B", 2); map.put("C", 3); map.put("D", 4);
map.keySet().stream().forEach(s -> System.out.println(s));
map.entrySet().stream().forEach(e -> System.out.println(e));
int[] arr = {1, 2, 3, 4, 5}; Arrays.stream(arr).forEach(e -> System.out.println(e));
Stream.of(1, 2, 3, 4, 5).forEach(e -> System.out.println(e)); } }
|
二、Stream流中间方法
| 名称 |
说明 |
| Stream<T> filter(Predicate<? super T> predicate) |
过滤 |
| Stream<T> limit(long maxSize) |
获取前几个元素 |
| Stream<T> skip(long n) |
跳过前几个元素 |
| Stream<T> distinct() |
元素去重,依赖(hashCode和equals方法) |
| static<T> Stream<T> concat(Stream a,Stream b) |
合并a和b两个流为一个流 |
| Stream<R> map(Function<T,R> mapper) |
转换流中的数据类型 |
注意:
- 中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
- 修改Stream流中的数据,不会影响原来集合或数组中的数据
2.1 filter():过滤
- Stream<T> filter(Predicate<? super T> predicate): 过滤
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import java.util.ArrayList; import java.util.Collections; import java.util.function.Predicate;
public class FilterDemo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); Collections.addAll(list, "张无忌", "周芷若", "张三丰", "赵敏", "张亮");
list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s)); } }
|
2.2 limit():获取前几个元素
- Stream<T> limit(long maxSize): 获取前几个元素
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import java.util.ArrayList; import java.util.Collections;
public class FilterDemo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); Collections.addAll(list, "张无忌", "周芷若", "张三丰", "赵敏", "张亮");
list.stream().limit(3).forEach(s -> System.out.println(s)); } }
|
2.3 skip():跳过前几个元素
- Stream<T> skip(long n): 跳过前几个元素
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import java.util.ArrayList; import java.util.Collections;
public class FilterDemo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); Collections.addAll(list, "张无忌", "周芷若", "张三丰", "赵敏", "张亮");
list.stream().skip(3).forEach(s -> System.out.println(s)); } }
|
2.4 distinct():元素去重
- Stream<T> distinct(): 元素去重,依赖(hashCode和equals方法)
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import java.util.ArrayList; import java.util.Collections;
public class StreamDemo1 { public static void main(String[] args) { ArrayList<String> list1 = new ArrayList<String>(); Collections.addAll(list1, "A", "A", "A", "B", "C", "C", "D");
list1.stream().distinct().forEach(s -> System.out.println(s)); } }
|
2.5 concat():合并两个流
- static<T> Stream<T> concat(Stream a,Stream b): 合并a和b两个流为一个流
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import java.util.ArrayList; import java.util.Collections; import java.util.stream.Stream;
public class StreamDemo1 { public static void main(String[] args) { ArrayList<String> list1 = new ArrayList<String>(); Collections.addAll(list1, "A", "A", "A", "B", "C", "C", "D");
ArrayList<String> list2 = new ArrayList<>(); Collections.addAll(list2, "E", "F", "G");
Stream.concat(list1.stream(), list2.stream()).forEach(s -> System.out.println(s)); } }
|
2.6 map:转换流中的数据类型
- Stream<R> map(Function<T,R> mapper): 转换流中的数据类型
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import java.util.ArrayList; import java.util.Collections; import java.util.function.Function;
public class MapDemo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张无忌-15", "周芷若-14", "赵敏-13", "张强-20", "张三丰-100");
list.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s->System.out.println(s));
} }
|
2025.04.11
三、Stream流终结方法
| 名称 |
说明 |
| void forEach(Consumer action) |
遍历 |
| long count() |
统计 |
| toArray() |
收集流中的数据,放到数组中 |
| collect(Collector collector) |
收集流中的数据,放到集合中 |
3.1 forEach():遍历
- void forEach(Consumer action): 遍历
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import java.util.ArrayList; import java.util.Collections; import java.util.function.Consumer;
public class ZhongjieDemo1 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张无忌", "周芷若", "张三丰", "赵敏", "张亮");
list.stream().forEach(s ->System.out.println(s)); } }
|
3.2 count():统计
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import java.util.ArrayList; import java.util.Collections;
public class ZhongjieDemo1 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张无忌", "周芷若", "张三丰", "赵敏", "张亮");
long count = list.stream().count(); System.out.println(count); } }
|
3.3 toArray():收集流中的数据,放到数组中
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import java.util.ArrayList; import java.util.Arrays; import java.util.function.IntFunction;
public class ZhongjieDemo1 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张无忌", "周芷若", "张三丰", "赵敏", "张亮");
String[] array = list.stream().toArray(value -> new String[value]); System.out.println(Arrays.toString(array)); } }
|
3.4 collect():收集流中的数据,放到集合中
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| import java.util.*; import java.util.function.Function; import java.util.stream.Collectors;
public class collectDemo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张无忌-男-15", "周芷若-女-14", "赵敏-女-13", "张强-男-20", "张三丰-男-100");
List<String> newList = list.stream() .filter(s -> "男".equals(s.split("-")[1])) .collect(Collectors.toList());
System.out.println(newList);
Set<String> newSet = list.stream() .filter(s -> "男".equals(s.split("-")[1])) .collect(Collectors.toSet());
System.out.println(newSet);
Map<String, Integer> newMap = list.stream() .filter(s -> "男".equals(s.split("-")[1])) .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("-")[2]); } }));
System.out.println(newMap); } }
|
四、练习
4.1 数据过滤
定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
过滤奇数,只留下偶数
并将结果保存起来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors;
public class StreamDemo2 { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); Collections.addAll(list,1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> collect = list.stream() .filter(s -> s % 2 == 0) .collect(Collectors.toList());
System.out.println(collect); } }
|
4.2 数据操作
创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
“zhangsan,23”
“lisi,24”
“wangwu,25”
保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import java.util.ArrayList; import java.util.Collections; import java.util.Map; import java.util.stream.Collectors;
public class StreamDemo3 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); Collections.addAll(list,"zhangsan,23","lisi,24","wangwu,25");
Map<String,Integer> map = list.stream() .filter(s -> Integer.parseInt(s.split(",")[1]) >=24) .collect(Collectors.toMap( s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1]) )); System.out.println(map); } }
|
4.3 数据操作
现在有两个ArrayList集合
第一个集合中:存储6名男演员的名字和年龄
第二个集合中:存储6名女演员的名字和年龄
姓名和年龄中间用逗号隔开,比如:张三,23
要求完成如下操作:
- 男演员只要名字为3个字的前两人
- 女演员只要姓林的,并且不要第一个人
- 把过滤后的男演员和女演员姓名合并在一起
- 将上一步的演员信息封装成Actor对象
- 将所有的演员对象都保存早List集合中
备注:演员类Actor,属性只有:name,age
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| public class Actor { private String name; private int age;
public Actor() { }
public Actor(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String toString() { return "Actor{name = " + name + ", age = " + age + "}"; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream;
public class StreamDemo4 { public static void main(String[] args) {
ArrayList<String> manList = new ArrayList<>(); Collections.addAll(manList, "周润发,23", "成龙,24", "刘德华,25", "吴京,26", "周星驰,27", "李连杰,28");
ArrayList<String> womanList = new ArrayList<>(); Collections.addAll(womanList, "林心如,18", "张曼玉,18", "林青霞,18", "柳岩,18", "林志玲,18", "王祖贤,18");
List<Actor> actorList = Stream.concat( manList.stream() .filter(s -> s.split(",")[0].length() == 3) .limit(2), womanList.stream() .filter(s -> s.split(",")[0].startsWith("林")) .skip(1)) .map(new Function<String, Actor>() { @Override public Actor apply(String s) { String[] split = s.split(","); return new Actor(split[0], Integer.parseInt(split[1])); } }) .collect(Collectors.toList());
System.out.println(actorList); } }
|
参考资料:
[1] 黑马程序员Java零基础视频教程_下部