目录
distinct 元素去重,依赖(hashcode和equal法)
concat(Stream a, Stream b) 合并a和b两个流为一个流
collect(Collector collector) 收集流中的数据,放到集合中(list,set,map)
一、定义一个集合,并添加一些数 1,2,3,4,5,6,7,8,9,10过滤奇数,只留下偶数。并将结果保存起来
在Java中,Stream流是一种用于处理数据的抽象概念。它可以用来操作集合、数组、输入/输出资源等,提供了一种统一的处理方式。
在Java 8中引入了Stream API,它可以让开发者更方便地处理数据集合,以函数式编程的方式进行操作。Stream流支持多种操作,可以分为两类:中间操作和终端操作。
中间操作是指在数据流中进行处理,可以用来过滤、映射、排序等操作。常用的中间操作有:filter、map、sorted等。
终端操作是指对数据流进行最终的处理,可以用来收集、计数、求和等操作。常用的终端操作有:collect、count、sum等。
Stream流的作用
结合了Lambda表达式,简化集合、数组的操作
Stream流的使用步骤:
先得到一条Stream流(流水线),并把数据放上去,再利用Stream流中的API进行各种操作
获取Stream流:
单列集合
方法名:
default Stream<E>stream()
collection中的默认方法
完整代码在这里
public class StreamDemo {
public static void main(String[] args) {
ArrayList<String>list=new ArrayList<>();
Collections.addAll(list,"a","b","c","d","e");
//获取到一条流水线,并把集合中的数据放到流水线上
Stream<String> stream1 = list.stream();
//使用终结方法打印一下流水线上的所有数据
stream1.forEach(s -> System.out.println(s));
}
}
双列集合
无法直接使用Stream流
可以先用keyset方法获取所有的键,再获取Stream流
也可以使用entryset方法获取所有的键值对对象,在获取Stream流
数组
方法名:
public static <T> Stream<T> stream(T[] array)
Arrays工具类中的静态方法
完整代码在这里
public class StreamDemo3 {
public static void main(String[] args) {
int[]arr={1,2,3,4,5};
Arrays.stream(arr).forEach(s-> System.out.println(s));
}
}
一堆零散的数组
方法名:
public static<T> stream<T> of(T... values)
Stream接口中的静态方法
注意:
Stream接口中静态方法of的细节:方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当做一个元素,放到stream当中。
基本数据类型:
引用数据类型:
Stream流的中间方法
Stream<T>filter(Predicate<? super T> predicate) 过滤
Stream<T>limit(long maxSize) 获取前几个元素
Stream<T> skip(long n) 跳过前几个元素
Stream<T> distinct() 元素去重,依赖(hashcode和equal法)
static <T>Stream<T>concat(Stream a, Stream b) 合并a和b两个流为一个流
Stream<R> map(Function<T ,R> mapper) 转换流中的数据类型
注意:
中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
修改Stream流中的数据,不会影响原来集合或者数组中的数据
filter过滤
练习: 把“张”开头的留下,其余数据过滤不要
上面是拿匿名内部类写的,可以用Lambda表达式简化一下👇
如果我在使用Stream1的话就会报错
表示在对流进行操作时,流已经被关闭👆,这就是注意的第一点
中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程👇
注意的第二点就字面的意思
修改Stream流中的数据,不会影响原来集合或者数组中的数据👇
limit获取前几个元素
练习:获取前三个元素
skip跳过前几个元素
例子: 跳过前三个元素
distinct 元素去重,依赖(hashcode和equal法)
例子:
重复的张三被去除了,我们来看看底层
hashset存储自定义元素的时候要重写hashcode和equals方法
concat(Stream a, Stream b) 合并a和b两个流为一个流
map转换流中的数据类型
例子:获取里面的年龄
第一个类型:流中原本的数据类型 第二个类型:要转成之后的类型 apply的形参s:依次表示流里面的每一个数据 返回值:表示转换之后的数据
用Lambda表达式表示👇
Stream流的终结方法
void forEach(Consumer action) 遍历
long count() 统计
toArray() 收集流中的数据,放到数组中
collect(Collector collector) 收集流中的数据,放到集合中
forEach遍历
Consumer的泛型:表示流中数据的类型
accept方法的形参s:依次表示流里面的每一个数据
方法体:对每一个数据的处理操作(打印)
用lambda表达式写
count()统计
toArray() 收集流中的数据,放到数组中
如果要收集指定类型的👇
IntFunction的泛型:具体类型的数组
apply的形参:流中数据的个数,要跟数组的长度保持一致
apply的返回值:具体类型的数组
方法体:就是创建数组
toArray方法的参数的作用:负贵创建一个指定类型的数组
toArray方法的底层,会依次得到流里面的每一个数据,并把数据放到数组当中
toArray方法的返回值:是一个装着流里面所有数据的数组
用lambda表达式👇
collect(Collector collector) 收集流中的数据,放到集合中(list,set,map)
例子:收集到list集合中,把所有男性收集起来
例子:收集到set集合中,把所有男性收集起来
拿收集到list集合跟set集合中与什么区别呢?
set集合会去除重复元素
例子:收集Map集合当中。把所有的男性收集起来。键:姓名, 值:年龄。
toMap :参数一表示键的生成规则
参数二表示值的生成规则
参数一:
Function 泛型一:表示流中每一个数据的类型
泛型二:表示Map集合中键的数据类型
方法apply形参:依次表示流里面的每一个数据方法体;生成键的代码
返回值:已经生成的键
参数二:
Function 泛型一:表示流中每一个数据的类型
泛型二:表示Map集合中值的数据类型
方法apply形参:依次表示流里面的每一个数据方法体;生成值的代码
返回值:已经生成的值
注意:如果我们要收集到Map集合当中。健不能重复。否则会报错
用lambda表达式写就是👇这样子
练习
一、定义一个集合,并添加一些数 1,2,3,4,5,6,7,8,9,10过滤奇数,只留下偶数。并将结果保存起来
完整代码在这里👇
public class StreamTest1 {
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> list1 = list.stream()
.filter(s -> s % 2 == 0)
.collect(Collectors.toList());
System.out.println(list1);
}
}
二、创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
"zhangsan,23"
"lisi,24"
"wangwu,25”
保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
完整代码在这里👇
public class StreamTest2 {
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);
}
}
三、现在有两个ArrayList集合
第一个集合中:存储6名男演员的名字和年龄。第二个集合中:存储6名女演员的名字和年龄。姓名和年龄中间用逗号隔开。比如:张三,23要求完成如下的操作:
1,男演员只要名字为2个字的前两人
2,女演员只要姓赵的,并且不要第一个
3,把过滤后的男演员姓名和女演员姓名合并到一起
4,将上一步的演员信息封装成Actor对象,
5,将所有的演员对象都保存到List集合中
备注:演员类Actor,属性有:name,age
Actor类
public class Actor {
private String name;
private int age;
public Actor() {
}
public Actor(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Actor{name = " + name + ", age = " + age + "}";
}
测试代码👇
public class StreamTest3 {
public static void main(String[] args) {
//创建两个集合并添加数据
ArrayList<String>manlist=new ArrayList<>();
Collections.addAll(manlist,"张三,15","李四,18","王五,20","赵六,15","张无忌,16","张三丰,28");
ArrayList<String>womenlist=new ArrayList<>();
Collections.addAll(womenlist,"赵敏,16","周芷若,18","小龙女,20","貂蝉,15","孙尚香,16","赵欣,28");
//男演员只要名字为2个字的前两人
Stream<String> stream1 = manlist.stream()
.filter(s -> s.split(",")[0].length() == 2)
.limit(2);
//女演员只要姓赵的,并且不要第一个
Stream<String> stream2 = womenlist.stream()
.filter(s -> s.split(",")[0].startsWith("赵"))
.skip(1);
//合并过滤后的男演员姓名与女演员姓名,演员信息封装为Actor对象
List<Actor> list = Stream.concat(stream1, stream2).map(s ->
new Actor(s.split(",")[0], Integer.parseInt(s.split(",")[1])))
.collect(Collectors.toList());
System.out.println(list);
}
}
stream流就说到这啦!!!感谢各位阅读!!继续努力努力再努力