🔥作者主页:小林同学的学习笔录
🔥mysql专栏:小林同学的专栏
目录
1.Stream流
1.1 概述
2.2 常见方法
2.2.1 实现步骤
2.2.2 获取Stream的方式
2.2.3 中间方法
2.2.4 终结方法
1.Stream流
1.1 概述
Stream流可以让你通过链式操作对集合中的元素进行过滤、映射、排序、组合等操作,这些操作都是惰性执行的,只有在终端操作(如forEach、collect等)被调用时才会触发实际计算。Stream流可以简化代码并提高代码的可读性,同时也可以让编译器更好地进行优化,提高代码的执行效率。
2.2 常见方法
Stream流的三类方法
-
获取Stream流
-
创建一条流水线,并把数据放到流水线上准备进行操作
-
-
中间方法
-
流水线上的操作
-
一次操作完毕之后,还可以继续进行其他操作
-
-
终结方法
-
一个Stream流只能有一个终结方法
-
是流水线上的最后一个操作
-
2.2.1 实现步骤
2.2.2 获取Stream的方式
代码实现:
public class Demo01 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.stream().forEach(s-> System.out.println(s));
}
}
输出结果:
1
2
3
Stream流中的方法大多数都是函数式接口,因此可以用lambda表达式来简化开发
Lambda表达式-CSDN博客
public class Demo02 {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("1",111);
map.put("2",222);
map.put("3",333);
map.entrySet().stream().forEach(s-> System.out.println(s));
}
}
输出结果:
1=111
2=222
3=333
public class Demo03 {
public static void main(String[] args) {
//数组可以通过Arrays中的静态方法stream生成流
String[] strArray = {"hello","world","java"};
Stream<String> strArrayStream = Arrays.stream(strArray);
//同种数据类型的多个数据可以通过Stream接口的静态方法of(T... values)生成流
Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");
Stream<Integer> intStream = Stream.of(10, 20, 30);
}
}
2.2.3 中间方法
代码实现:
public class Demo04 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"林俊杰","林忆莲","周杰伦","周兴哲");
//传统方法(只展示出开头为林的歌手)
// list.stream().filter(new Predicate<String>() {
// @Override
// public boolean test(String s) {
// //true表示不会被过滤掉,false就会被过滤
// return s.startsWith("林");
// }
// }).forEach(s -> System.out.println(s));
// 用stream + lambda表达式
list.stream()
.filter(s -> s.startsWith("林"))
.forEach(s -> System.out.println(s));
}
}
输出结果:
林俊杰
林忆莲
public class Demo05 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"1","2","3");
// list.stream().map(new Function<String, Integer>() {
// @Override
// public Integer apply(String s) {
// return Integer.parseInt(s);
// }
// }).forEach(s-> System.out.println(s.getClass() + " " + s));
//用lambda表达式后
list.stream()
.map(s -> Integer.parseInt(s))
.forEach(s-> System.out.println(s.getClass() + " " + s));
}
}
输出结果:
class java.lang.Integer 1
class java.lang.Integer 2
class java.lang.Integer 3
2.2.4 终结方法
代码演示:
public class Demo06 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"林俊杰","林忆莲","周杰伦","周兴哲");
// toArray() 收集流中的数据,放到数组中
//Object[] arr1 = list.stream().toArray();
//System.out.println(Arrays.toString(arr1));
//IntFunction的泛型:具体要保存的数据类型
//apply的形参:流中的数据个数,要跟数组的长度保持一致
//apply的返回值:具体要保存的数据类型,这里需要指定values个数,不然会报错
String[] array = list.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
});
System.out.println(Arrays.toString(array));
}
}
输出结果:
[林俊杰, 林忆莲, 周杰伦, 周兴哲]
public class Demo07 {
public static void main(String[] args) {
/*
collect(Collector collector) 收集流中的数据,放到集合中 (List Set Map)
注意点:
如果我们要收集到Map集合当中,键不能重复,否则会报错
*/
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌-男-15", "周芷若-女-14", "赵敏-女-13", "张强-男-20",
"张三丰-男-100", "张翠山-男-40", "张良-男-35", "王二麻子-男-37", "谢广坤-男-41");
//收集List集合当中
//需求:
//我要把所有的男性收集起来
List<String> newList1 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toList());
//System.out.println(newList1);
//收集Set集合当中
//需求:
//我要把所有的男性收集起来
Set<String> newList2 = list.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
//System.out.println(newList2);
//收集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) {
//张无忌-男-15
return s.split("-")[0];
}
},
new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split("-")[2]);
}
}));
Map<String, Integer> map2 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(
s -> s.split("-")[0],
s -> Integer.parseInt(s.split("-")[2])));
System.out.println(map2);
}
}
3.3 综合案例
第一题
public class Test01 {
public static void main(String[] args) {
//需求:定义一个集合,并且添加1-10的元素,过滤奇数,只留下偶数,并且保存起来
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,1,2,3,4,5,6,7,8,9,10);
List<Integer> collect = list.stream()
.filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
//true就留下
return integer % 2 == 0;
}
}).collect(Collectors.toList());
//System.out.println(collect);
//用lambda表达式简化开发
List<Integer> collect1 = list.stream()
.filter(s -> s % 2 == 0)
.collect(Collectors.toList());
System.out.println(collect1);
}
}
第二题
public class Test02 {
public static void main(String[] args) {
// 需求 :
// 创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
// "zhangsan,23"
// "lisi,24"
// "wangwu,25"
// 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
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(
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(map);
Map<String, Integer> map1 = 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(map1);
}
}
第三题
public class Test03 {
public static void main(String[] args) {
// 现在有两个ArrayList集合,分别存储6名男演员的名字和年龄以及6名女演员的名字和年龄。
// 姓名和年龄中间用逗号隔开。
// 比如:张三,23
// 要求完成如下的操作:
// 1,男演员只要名字为3个字的前两人
// 2,女演员只要姓杨的,并且不要第一个
// 3,把过滤后的男演员姓名和女演员姓名合并到一起
// 4,将上一步的演员信息封装成Actor对象。
// 5,将所有的演员对象都保存到List集合中。
// 备注:演员类Actor,属性有:name,age
//
// 男演员: "蔡坤坤,24" , "叶齁咸,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27"
// 女演员: "赵小颖,35" , "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33"
ArrayList<String> manList = new ArrayList<>();
ArrayList<String> womenList = new ArrayList<>();
Collections.addAll(manList,"蔡坤坤,24" , "叶齁咸,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27");
Collections.addAll(womenList,"赵小颖,35" , "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33");
Stream<String> stream = manList.stream()
.filter(s -> s.split(",")[0].length() == 3)
.limit(2);
Stream<String> stream1 = womenList.stream()
.filter(s -> s.startsWith("杨"))
.skip(1);
//这里面的数据是String,想要转为Actor对象需要map()来实现
// Stream.concat(stream,stream1).map(new Function<String, Actor>() {
// @Override
// public Actor apply(String s) {
// String name = s.split(",")[0];
// int age = Integer.parseInt(s.split(",")[1]);
// return new Actor(name,age);
// }
// }).forEach(s-> System.out.println(s));
//简化
Stream.concat(stream,stream1).map(s ->
new Actor(s.split(",")[0],Integer.parseInt(s.split(",")[1])))
.forEach(s -> System.out.println(s));
}
}