Stream流
1. 初始Stream流
-
Stream流的作用: 结合了Lambda表达式, 简化集合和数组的操作
-
Stream流的使用步骤:
- (1) 先得到一条Stream流(流水线), 并把数据放上去
- (2) 利用Stream流中的API进行各种操作
各种操作主要包含两种: (1) 中间方法: 如过滤和转换(方法调用完毕之后, 还可以调用其他方法) (2) 终结方法: 如统计和打印(最后一步调用完毕之后, 不能调用其他方法)
2. Stream流的使用步骤
2.1 先得到一条Stream流(流水线), 并把数据放上去
- 对于无法直接使用Stream流的双列集合, 需要使用方法keySet或者entrySet先转换成单列集合

// 1. 单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c", "d", "e");
// 获取到一条流水线, 并且把集合中的数据映射到Stream流中
// Stream<String> stream1 = list.stream();
// 使用终结符方法, 打印集合中的数据
// (1) lamda写法
// stream1.forEach(new Consumer<String>() {
// @Override
// public void accept(String s) {
// System.out.println(s);
// }
// });
// (2) 化简写法
list.stream().forEach(s -> System.out.println(s));
// 2. 双列集合获取Stream流(需要用单列集合转换)
HashMap<String, Integer> hm = new HashMap<>();
hm.put("aa", 1);
hm.put("bb", 2);
hm.put("cc", 3);
// (1) 第一种获取Stream流
hm.keySet().stream().forEach(s -> System.out.println(s)); // "aa", "bb", "cc", "dd"
// (1) 第二种获取Stream流
hm.entrySet().stream().forEach(entry -> System.out.println(entry.getKey())); // "aa", "bb", "cc", "dd"
// 3. 数组获取Stream流
int[] arr = {1, 2, 3, 4, 5};
Arrays.stream(arr).forEach(i -> System.out.println(i));
// 4. 一堆零散数据获取Stream流(需要确保数据类型相同)
Stream.of(1, 2, 3, 4, 5).forEach(i -> System.out.println(i));
- Stream接口中静态方法of的细节:
- 方法的形参是一个可变参数, 可以传递一堆零散的数据, 也可以传递数组
- 数组必须是引用数据类型的, 若为基本数据类型, 会把数组整体当一个元素, 放在Stream, 打印出地址值
2.2 Stream流的中间方法
- 中间方法, 返回新的Stream流, 原来的Stream流只能使用一次, 建议使用链式编程
- 修改Stream流中的数据, 不会影响原来集合或者数组中的数据

1. filter过滤
// 1. 单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三", "张无忌", "里斯", "王五");
// filter过滤 把张开头的留下,其余数据过滤不要
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
// 如果返回值为true,则数据保留
return s.startsWith("张");
}
}).forEach(s -> System.out.println(s));
list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s));
2. limit获取前几个元素
// 1. 单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三", "张无忌", "里斯", "王五");
// 获取前三个元素
list.stream().limit(3)
.forEach(s-> System.out.println(s));
3. skip获取前几个元素
// 1. 单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三", "张无忌", "里斯", "王五");
// 跳过前三个元素
list.stream().skip(3)
.forEach(s-> System.out.println(s));
4. distinct去重
- 记得手写equals和hashCode方法
// 1. 单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三", "张无忌", "里斯", "王五", "王五");
list.stream().distinct().forEach(s-> System.out.println(s));
5. concat合并
// 1. 单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三", "张无忌", "里斯", "王五", "王五");
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2, "liu");
Stream.concat(list.stream(), list2.stream())
.forEach(s-> System.out.println(s));
6. map转换流中的数据类型
// 1. 单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-18", "张无忌-19", "里斯-20", "王五-21", "王五-26");
// 只获取里面的年龄并打印: String->int
// 第一个类型: 流中原本的数据类型
// 第二个类型: 流中想要获取的数据类型
// 当map方法执行完之后, s依次表示流中的每一个数据, 为整数
list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
String[] arr = s.split("-");
String ageStr = arr[1];
int age = Integer.parseInt(ageStr);
return age;
}
}).forEach(s->System.out.println(s));
list.stream().map(s->Integer.parseInt(s.split("-")[1]))
.forEach(s->System.out.println(s));
2.3 Stream流的终结方法

1. forEach()
// 1. 单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-18", "张无忌-19", "里斯-20", "王五-21", "王五-26");
// 只获取里面的年龄并打印: String->int
// 第一个类型: 流中原本的数据类型
// 第二个类型: 流中想要获取的数据类型
// 当map方法执行完之后, s依次表示流中的每一个数据, 为整数
list.stream().map(s->Integer.parseInt(s.split("-")[1]))
.forEach(s->System.out.println(s));
2. count()统计
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-18", "张无忌-19", "里斯-20", "王五-21", "王五-26");
System.out.println(list.stream().count());
3. toArray()收集流中的数据并放到数组中
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-18", "张无忌-19", "里斯-20", "王五-21", "王五-26");
// 1. 无参
Object[] array = list.stream().toArray();
System.out.println(Arrays.toString(array));
// 2. 带参如下图
// IntFunction的范型: 具体类型的数组
// apply的形参: 流中数据的个数, 要跟数组的长度保持一致
// apply的返回值: 具体类型的数组
// 方法体: 就是创建数组
// list.stream().toArray(new IntFunction<? extends Object[]>() {
// @Override
// public Object[] apply(int value) {
// return new Object[0];
// }
// })
String[] array1 = list.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
});
System.out.println(Arrays.toString(array1));
String[] array2 = list.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(array2));
4. collector
1. 收集到List集合当中
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-男-18", "张无忌-男-19", "里斯-男-20", "王五-女-21");
// 收集到List集合当中
// 需求: 把所有的男性收集起来
List<String> list1 = list.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toList());
System.out.println(list1);
2. 收集到Set集合当中
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-男-18", "张无忌-男-19", "里斯-男-20", "王五-女-21");
// 收集到List集合当中
// 需求: 把所有的男性收集起来
Set<String> set1 = list.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
System.out.println(set1);
3. 收集到Map集合当中
如果我们要收集到Map集合当中, 键不能重复, 否则会报错
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-男-18", "张无忌-男-19", "里斯-男-20", "王五-女-21");
// 收集到Map集合当中
// 需求: 把所有的男性收集起来
// 键: 姓名, 值: 年龄
// toMap先写键的规则, 再写值的规则
Map<String, Integer> map1 = list.stream()
.filter(s -> s.split("-")[1].equals("男"))
/*
toMap: 参数一表示键的生成规则, 参数二表示值的生成规则
参数一:
Function范型一: 表示流中每一个数据类型
范型二: 表示Map集合中的键的类型
方法apply形参: 依次表示流中的每一个数据
方法apply返回值: 键
参数二:
Function范型一: 表示流中每一个数据类型
范型二: 表示Map集合中的值的类型
方法apply形参: 依次表示流中的每一个数据
方法apply返回值: 值
*/
.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(map1);
Map<String, Integer> map2 = list.stream().filter(s -> s.split("-")[1].equals("男"))
.collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.parseInt(s.split("-")[2])));
System.out.println(map2);

浙公网安备 33010602011771号