Stream流的思想
流水线思想-->
例:
先进入xx条件过滤,再进入xx条件过滤,......,输出
作用
结合Lambda表达式,简化集合、数组的操作
使用步骤
演示
单列集合->
public static void main(String[] args) {
//单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c", "d", "e");
//获取到一条流水线,并把集合中的数据放到流水线上
Stream<String> stream1 = list.stream();
//使用终结方法打印流水线上的所有数据
/*stream1.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
//s:依次表示流水线上的每一个数据
System.out.println(s);
}
});*/
//一般用Lambda表达式+链式编程简化
list.stream().forEach(s -> System.out.print(s));//结果abcde
}
双列集合->
public static void main(String[] args) {
//创建双列集合
HashMap<String,Integer> hm = new HashMap<>();
//添加数据
hm.put("aaa",111);
hm.put("bbb",222);
hm.put("ccc",333);
//第一种:获取stream流
hm.keySet().stream().forEach(s -> System.out.print(s));//结果aaacccbbb
//第二种:获取stream流
hm.entrySet().stream().forEach(s -> System.out.println(s));//结果aaa=111 ccc=333 bbb=222
}
数组演示->
public static void main(String[] args) {
//创建数组
int[] arr = {1,2,3,4,5,6,7,8,9,10};
//获取stream流
Arrays.stream(arr).forEach(s -> System.out.print(s));//结果:12345678910
}
一堆零散的数据->
public static void main(String[] args) {
Stream.of(1,2,3,4,5).forEach(s -> System.out.print(s));//结果:12345
}
注意
Stream流的中间方法
方法演示
filter方法->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
//filter 过滤
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
//返回值为true:表示当前数据留下
//返回值为false:表示当前数据舍弃不要
return s.startsWith("张");
}
}).forEach(s -> System.out.print(s + " "));//结果:张无忌 张强 张三丰 张翠山 张良
代码简化Lambda表达式-->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
//filter 过滤
list.stream().filter((String s) -> s.startsWith("张")).forEach(s -> System.out.print(s + " "));//结果:张无忌 张强 张三丰 张翠山 张良
limit方法->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
//limit 获取前几个元素
list.stream().limit(3).forEach(s -> System.out.print(s + " "));//张无忌 周芷若 赵敏
skip方法->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
//skip 跳过前几个元素
list.stream().skip(3).forEach(s -> System.out.print(s + " "));//张强 张三丰 张翠山 张良 王二麻子 谢广坤
distinct方法->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","张无忌","张无忌","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
Collections.addAll(list,"周芷若","赵敏");
//distinct 元素去重(依赖hashCode和equals方法)
list.stream().distinct().forEach(s -> System.out.print(s + " "));//张无忌 张强 张三丰 张翠山 张良 王二麻子 谢广坤 周芷若 赵敏
concat方法->
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌","张无忌","张无忌","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2,"周芷若","赵敏");
//concat 合并a和b两个流为一个流
Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.print(s + " "));//张无忌 张无忌 张无忌 张强 张三丰 张翠山 张良 王二麻子 谢广坤 周芷若 赵敏
map方法->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-15","周芷若-14","赵敏-18","张强-11","张三丰-25","张翠山-28","张良-30","王二麻子-38","谢广坤-22");
//只获取里面的年龄并进行打印 String->int
//第一个类型:表示流中原本的数据类型
//第二个类型:表示要转成之后的类型
//apply的形参s:依次表示流里面的每一个数据
//返回值:转换之后的数据
list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s){
String[] arr = s.split("-");
String ageString = arr[1];
int age = Integer.parseInt(ageString);
return age;
}
}).forEach(s -> System.out.print(s + " "));//15 14 18 11 25 28 30 38 22
Lambda简化-->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-15","周芷若-14","赵敏-18","张强-11","张三丰-25","张翠山-28","张良-30","王二麻子-38","谢广坤-22");
//只获取里面的年龄并进行打印 String->int
//第一个类型:表示流中原本的数据类型
//第二个类型:表示要转成之后的类型
//apply的形参s:依次表示流里面的每一个数据
//返回值:转换之后的数据
list.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s -> System.out.print(s + " "));//15 14 18 11 25 28 30 38 22
Stream流的终结方法
方法演示
forEach方法->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
//void forEach(Consumer action) 遍历
//Consumer泛型:表示流中数据的类型
//accept方法的形参s:依次表示流中的每一个数据
//方法体:对每一个数据的处理操作
list.stream().forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
简化代码-->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
list.stream().forEach((String s) -> System.out.println(s));
count方法->
//long count() 统计
long count = list.stream().count();
System.out.println(count);//9
toArray方法->空参
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
//toArray() 收集流中的数据,放到数据中
Object[] arr1 = list.stream().toArray();
System.out.print(Arrays.toString(arr1));//[张无忌, 周芷若, 赵敏, 张强, 张三丰, 张翠山, 张良, 王二麻子, 谢广坤]
toArray方法->带参
//toArray() 收集流中的数据,放到数据中
//IntFunction的泛型:具体类型的数组
//apply的形参:流中数据的个数,要跟数组的长度保持一致
//apply的返回值:具体类型的数组
//方法体:就是创建数组
//toArray方法的作用:负责创建一个指定类型的数组
//toArray方法的底层:会依次得到流里面的每一个数据,并把数据放到数组当中
//toArray方法的返回值:是一个装着流里面所有数据的数组
String[] arr = list.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
});
System.out.println(Arrays.toString(arr));//[张无忌, 周芷若, 赵敏, 张强, 张三丰, 张翠山, 张良, 王二麻子, 谢广坤]
简写-->
String[] arr = list.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(arr));//[张无忌, 周芷若, 赵敏, 张强, 张三丰, 张翠山, 张良, 王二麻子, 谢广坤]
collect方法->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-男-15","周芷若-女-14","赵敏-女-18","张强-男-11",
"张三丰-男-25","张翠山-男-28","张良-男-30","王二麻子-男-38","谢广坤-男-22");
/*
收集List集合当中
需求:
把所有男性收集起来
*/
List<String> newList = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());
System.out.println(newList);//[张无忌-男-15, 张强-男-11, 张三丰-男-25, 张翠山-男-28, 张良-男-30, 王二麻子-男-38, 谢广坤-男-22]
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-男-15","张无忌-男-15","张无忌-男-15","周芷若-女-14","赵敏-女-18","张强-男-11",
"张三丰-男-25","张翠山-男-28","张良-男-30","王二麻子-男-38","谢广坤-男-22");
/*
收集Set集合当中
需求:
把所有男性收集起来
*/
Set<String> newList2 = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toSet());
System.out.println(newList2);//[张三丰-男-25, 张良-男-30, 张无忌-男-15, 张强-男-11, 张翠山-男-28, 谢广坤-男-22, 王二麻子-男-38]
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-男-15","周芷若-女-14","赵敏-女-18","张强-男-11",
"张三丰-男-25","张翠山-男-28","张良-男-30","王二麻子-男-38","谢广坤-男-22");
/*
收集Map集合当中
需求:
把所有男性收集起来
键:姓名,值:年龄
*/
Map<String, Integer> map = list.stream().filter(s -> "男"
.equals(s.split("-")[1]))
/*
toMap:参数一表示键的生成规则
参数二表示值的生成规则
参数一:
Function泛型一:表示流中每一个数据的类型
泛型二:表示Map集合中键的数据类型
方法apply形参:依次表示流里面的每一个数据
方法体:生成键的代码
返回值:已经生成的键
参数二:
Function泛型一:表示流中每一个数据的类型
泛型二:表示Map集合中值的数据类型
方法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(map);//{张强=11, 张良=30, 张翠山=28, 王二麻子=38, 张三丰=25, 张无忌=15, 谢广坤=22}
简化代码-->
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-男-15","周芷若-女-14","赵敏-女-18","张强-男-11",
"张三丰-男-25","张翠山-男-28","张良-男-30","王二麻子-男-38","谢广坤-男-22");
/*
收集Map集合当中
需求:
把所有男性收集起来
键:姓名,值:年龄
*/
Map<String, String> map = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(
s -> s.split("-")[0]
,
s -> s.split("-")[2]
));
System.out.println(map);//{张强=11, 张良=30, 张翠山=28, 王二麻子=38, 张三丰=25, 张无忌=15, 谢广坤=22}