作用:
结合了Lambda表达式,简化集合、数组的操作
使用步骤:
①得到一条Stream流(流水线),并把数据放上去
②使用中间方法(如过滤、转换)对流水线上的数据进行操作
③使用终结方法(如统计、打印)对流水线上的数据进行操作
使用方法:
简单代码演示:
单列集合:
要求:
将集合中以a开头且长度为3的元素提取出来
代码演示:
java
public class StreamDemo1 {
public static void main(String[] args) {
//将以a开头且长度为3的元素提取出来
//创建集合
ArrayList<String> list = new ArrayList<>();
//添加元素
list.add("aa");
list.add("bbb");
list.add("abc");
list.add("aaa");
list.add("cca");
//使用Stream流筛选
list.stream().filter(str -> str.startsWith("a"))
.filter(str -> str.length() == 3)
.forEach(str -> System.out.println(str));
}
}
(代码思想可以理解为先进行过滤操作留下以a开头的,再进行过滤操作留下长度为3的,最后输出)
运行结果:
双列集合:
代码演示:
java
public class StreamDemo2 {
public static void main(String[] args) {
HashMap<String,String> hm = new HashMap<>();
hm.put("a","1");
hm.put("b","2");
hm.put("c","3");
//双列集合不能直接使用Stream
//所以使用其他两种方法
//1.对键使用Stream
hm.keySet().stream().forEach(str -> System.out.println(str));
//2.对键值对使用Stream
hm.entrySet().stream().forEach(str -> System.out.println(str));
}
}
运行结果:
数组:
代码演示:
java
public class StreamDemo3 {
public static void main(String[] args) {
int[] arr1 = {1,2,3,4,5};
Arrays.stream(arr1).forEach(num -> System.out.println(num));
String[] arr2 = {"a","b","c"};
Arrays.stream(arr2).forEach(str -> System.out.println(str));
}
}
运行结果:
零散数据:
代码演示:
java
public class StreamDemo4 {
public static void main(String[] args) {
Stream.of(1,2,3,4,5).forEach(num -> System.out.println(num));
Stream.of("a","b","c").forEach(str -> System.out.println(str));
}
}
运行结果:
Stream流的中间方法
注意:
1.中间方法会返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
2.修改Stream流中的数据,不会影响到原来集合或数组中的数据
代码演示:
java
public class StreamDemo5 {
public static void main(String[] args) {
//filter 过滤
//limit 获取前几个元素
//skip 跳过前几个元素
//distinct 元素去重(依赖hashCode和equals方法)
//concat(Stream a, Stream b) 合并a和b两个流为一个流
//map 转换流中的数据类型
//创建集合并添加元素
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"蔡徐坤","陈立农","范丞丞","黄明昊"
,"林彦俊","朱正廷","王子异","王琳凯","尤长靖");
//我是ikun别骂我(摘自流行歌曲《我的少年》)
//分为三部分演示
//1.
//filter 过滤
//limit 获取前几个元素
//skip 跳过前几个元素
System.out.println("----------1----------");
//filter 过滤
//返回王姓人物
//1.使用Lambda表达式
list.stream()
.filter(s -> s.startsWith("王"))
.forEach(s -> System.out.println(s));
//2.未使用Lambda表达式时
/*list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("王");
}
}).forEach(s -> System.out.println(s));*/
//limit 获取前几个元素
System.out.println();
list.stream()
.limit(3)
.forEach(s -> System.out.println(s));
//skip 跳过前几个元素
System.out.println();
list.stream()
.skip(5)
.forEach(s -> System.out.println(s));
//练习 获取这三位 "黄明昊","林彦俊","朱正廷"
System.out.println();
list.stream()
.skip(3)
.limit(3)
.forEach(s -> System.out.println(s));
//2.
//distinct 元素去重(依赖hashCode和equals方法)
//concat(Stream a, Stream b) 合并a和b两个流为一个流
System.out.println("----------2----------");
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1,"蔡徐坤","蔡徐坤","蔡徐坤","陈立农","陈立农","范丞丞");
ArrayList<String> list2= new ArrayList<>();
Collections.addAll(list2,"黄明昊","林彦俊","朱正廷","王子异","王琳凯","尤长靖");
//distinct 元素去重(依赖hashCode和equals方法)
list1.stream().distinct().forEach(s -> System.out.println(s));
//concat(Stream a, Stream b) 合并a和b两个流为一个流
System.out.println();
Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.println(s));
//3.
//map 转换流中的数据类型
System.out.println("----------3----------");
//创建集合并存储元素
ArrayList<String> list3 = new ArrayList<>();
Collections.addAll(list3,"蔡徐坤-18","陈立农-19","范丞丞-20","黄明昊-21"
,"林彦俊-22","朱正廷-23","王子异-24","王琳凯-25","尤长靖-26");
//1.不使用Lambda
list3.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
String[] arr = s.split("-");
String ageString = arr[1];
int num = Integer.parseInt(ageString);
return num;
}
}).forEach(s -> System.out.print(s + " "));
//2.使用Lambda
System.out.println();
list3.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s -> System.out.print(s + " "));
}
运行结果:
Stream流的终结方法:
代码演示:
这里先演示前三个方法,collect后面独立演示
java
public class StreamDemo6 {
public static void main(String[] args) {
//创建集合并添加元素
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"蔡徐坤","陈立农","范丞丞","黄明昊"
,"林彦俊","朱正廷","王子异","王琳凯","尤长靖");
// void forEach(Consumer action) 遍历
System.out.println("----------------------------");
//使用Lambda
list.stream().forEach(s -> System.out.print(s + " "));
//不使用Lambda
System.out.println();
list.stream().forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.print(s + " ");
}
});
// long count() 统计
System.out.println();
System.out.println("----------------------------");
long count = list.stream().count();
System.out.println(count);
// toArray() 收集流中的数据,放到数组中
System.out.println("----------------------------");
//空参构造
Object[] array1 = list.stream().toArray();
System.out.println(Arrays.toString(array1));
//带参构造
String[] array2 = list.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
});
System.out.println(Arrays.toString(array2));
//Lambda表达式
String[] array3 = list.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(array3));
}
}
运行结果:
collect方法代码演示
java
public class StreamDemo7 {
public static void main(String[] args) {
//collect(Collector collector) 收集流中的数据,放到集合中
//创建集合并添加元素
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"小白-男-20","小白-男-20","小黑-男-21","小红-女-22","小蓝-男-23","小紫-女-24");
//1.放到List集合
//要求:筛选男性
List<String> newList = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toList());
System.out.println(newList);
//2.放到Set集合
//要求:筛选男性
//放到Set集合中会去重
Set<String> newSet = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
System.out.println(newSet);
//3.放到Map集合
//要求:筛选男性 并且将姓名作为键,将年龄作为值
//注意:放入Map集合中要求集合中不得有相同的键
//调用toMap()后括号中的两个参数为键的规则和值的规则
//创建新集合
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1,"小白-男-20","小黑-男-21","小红-女-22","小蓝-男-23","小紫-女-24");
//未使用Lambda表达式
Map<String, Integer> newMap = list1.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);
//使用Lambda表达式
Map<String, Integer> newMap2 = list1.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.parseInt(s.split("-")[2])));
System.out.println(newMap2);
}
}
运行结果:
三个小练习
练习一:
定义一个集合,并添加一些整数
1,2,3,4,5,6,7,8,9,10
过滤奇数,只留下偶数
并将结果保存
代码:
java
public class StreamTest1 {
public static void main(String[] args) {
/*
定义一个集合,并添加一些整数
1,2,3,4,5,6,7,8,9,10
过滤奇数,只留下偶数
并将结果保存
*/
//创建集合并添加元素
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,1,2,3,4,5,6,7,8,9,10);
//过滤奇数,并存储到新集合
List<Integer> newList = list.stream().filter(num -> num % 2 == 0).collect(Collectors.toList());
System.out.println(newList);
}
}
运行结果:
练习二:
创建一个ArrayList集合,并添加以下字符串
字符串中前面是姓名,后面是年龄
"zhangsan,23" "lisi,24" "wangwu,25"
保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
代码:
java
public class StreamTest2 {
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");
//保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
Map<String, Integer> newMap = 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(newMap);
}
}
运行结果:
练习三:
现在有两个ArratList集合,
第一个集合中存储6名男演员的名字和年龄
第二个集合中存储6名女演员的名字和年龄
姓名和年龄中间用逗号隔开,比如:张三,23
要求完成如下的操作
1.男演员只要名字为3个字的前两人
2.女演员只要姓杨的,并且不要第一个
3.把过滤后的男演员和女演员姓名合并到一起
4.将上一步的演员信息封装成Actor对象
5.将所有的演员对象都保存到List集合中
备注:演员类Actor,属性:name,age
代码:
java
public class StreamTest3 {
public static void main(String[] args) {
/*
现在有两个ArratList集合,
第一个集合中存储6名男演员的名字和年龄
第二个集合中存储6名女演员的名字和年龄
姓名和年龄中间用逗号隔开,比如:张三,23
要求完成如下的操作
1.男演员只要名字为3个字的前两人
2.女演员只要姓杨的,并且不要第一个
3.把过滤后的男演员和女演员姓名合并到一起
4.将上一步的演员信息封装成Actor对象
5.将所有的演员对象都保存到List集合中
备注:演员类Actor,属性:name,age
*/
//创建集合并存储元素
ArrayList<String> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list1,"彭于晏,30","吴彦祖,31","周星驰,32",
"古天乐,33","刘德华,34","周润发,35");
Collections.addAll(list2,"杨紫,21","杨颖,22","刘亦菲,23",
"高圆圆,24","杨超越,25","孙千,26");
//1.男演员只要名字为3个字的前两人
Stream<String> stream1 = list1.stream()
.filter(s -> s.split(",")[0].length() == 3)
.limit(2);
//2.女演员只要姓杨的,并且不要第一个
Stream<String> stream2 = list2.stream()
.filter(s -> s.split(",")[0].startsWith("杨"))
.skip(1);
//3.把过滤后的男演员和女演员姓名合并到一起
Stream<String> stream3 = Stream.concat(stream1, stream2);
//4.将上一步的演员信息封装成Actor对象
Stream<Actor> actorStream = stream3
.map(s -> new Actor(s.split(",")[0], Integer.parseInt(s.split(",")[1])));
//5.将所有的演员对象都保存到List集合中
List<Actor> actorList = actorStream.collect(Collectors.toList());
System.out.println(actorList);
}
}