文章目录
一、体验Stream流
- 案例需求
按照下面的要求完成集合的创建和遍历
- 创建一个集合,存储多个字符串元素
- 把集合中所有以"张"开头的元素存储到一个新的集合
- 把"张"开头的集合中的长度为3的元素存储到一个新的集合
- 遍历上一步得到的集合
不使用Stream流的代码:
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>(List.of("张三丰", "张无忌", "张翠山", "王二麻子", "张良", "谢广坤"));
ArrayList<String> list2 = new ArrayList<>();
for (String s : list1) {
if (s.startsWith("张")) {
list2.add(s);
}
}
ArrayList<String> list3 = new ArrayList<>();
for (String s : list2) {
if (s.length() == 3) {
list3.add(s);
}
}
for (String s : list3) {
System.out.println(s);
}
}
}
张三丰
张无忌
张翠山
使用Stream流的代码:
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>(List.of("张三丰", "张无忌", "张翠山", "王二麻子", "张良", "谢广坤"));
list1.stream().filter(s -> s.startsWith("张"))
.filter(s -> s.length() == 3)
.forEach(s -> System.out.println(s));
}
}
张三丰
张无忌
张翠山
二、Stream流概述
Stream流:流水线 用来优化操作集合代码,基于匿名内部类的延迟执行现象,是JDK8的新特性。
使用String流的好处:
- 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印
- Stream流把真正的函数式编程风格引入到Java中
- 代码简洁
三、Stream流的三类方法
- 获取Stream流
- 创建一条流水线,并把数据放到流水线上准备进行操作
- 中间方法
- 流水线上的操作
- 一次操作完毕之后,还可以继续进行其他操作
- 终结方法
- 一个Stream流只能有一个终结方法
- 是流水线上的最后一个操作
四、生成Stream流的方式
- Collection体系集合
使用默认方法stream()生成流, default Stream stream() - Map体系集合
把Map转成Set集合,间接的生成流 - 数组
通过Arrays中的静态方法stream生成流 - 同种数据类型的多个数据
通过Stream接口的静态方法of(T… values)生成流
import java.util.*;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
//Collection体系的集合可以使用默认方法stream()生成流
List<String> list = new ArrayList<String>();
Stream<String> listStream = list.stream();
Set<String> set = new HashSet<String>();
Stream<String> setStream = set.stream();
//Map体系的集合间接的生成流
Map<String,Integer> map = new HashMap<String, Integer>();
Stream<String> keyStream = map.keySet().stream();
Stream<Integer> valueStream = map.values().stream();
Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();
//数组可以通过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);
}
}
五、Stream流中间操作方法
中间操作的意思是:执行完此方法之后,Stream流依然可以继续执行其他操作。
方法名 | 说明 |
---|---|
Stream filter(Predicate predicate) | 用于对流中的数据进行过滤 |
Stream limit(long maxSize) | 返回此流中的元素组成的流,截取前指定参数个数的数据 |
Stream skip(long n) | 跳过指定参数个数的数据,返回由该流的剩余元素组成的流 |
static Stream concat(Stream a, Stream b) | 合并a和b两个流为一个流 |
Stream distinct() | 返回由该流的不同元素(根据Object.equals(Object) )组成的流 |
六、Stream流终结操作方法
终结操作的意思是:执行完此方法之后,Stream流将不能再执行其他操作。
方法名 | 说明 |
---|---|
void forEach(Consumer action) | 对此流的每个元素执行操作 |
long count() | 返回此流中的元素数 |
七、Stream流的收集操作
对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中。
方法名 | 说明 |
---|---|
R collect(Collector collector) | 把结果收集到集合中 |
Collectors具体的收集方法:
方法名 | 说明 |
---|---|
public static Collector toList() | 把元素收集到List集合中 |
public static Collector toSet() | 把元素收集到Set集合中 |
public static Collector toMap(FunctionkeyMapper,FunctionvalueMapper) | 把元素收集到Map集合中 |
八、Stream流的综合练习
- 案例需求
现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作:
1. 男演员只要名字为3个字的前三人。
2. 女演员只要姓林的,并且不要第一个。
3. 把过滤后的男演员姓名和女演员姓名合并到一起。
4. 合并到一起之后,去掉重复的名字,然后返回把这些元素存储到一个新的List集合中。
5. 把上一步操作后的集合里面的元素 每个元素 封装到 演员对象中,把所有的演员对象 存储到一个新的集合中。
6. 统计这个新集合里面演员名字是两个字的人员个数。
演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
list1.add("张一一");
list1.add("张二一");
list1.add("林四一");
list1.add("张四一");
list1.add("张五一");
list2.add("林一一");
list2.add("李二一");
list2.add("张三一");
list2.add("林四");
list2.add("林五一");
System.out.println(Stream.concat(list1.stream().filter(s -> s.length() == 3).limit(3),
list2.stream().filter(s -> s.startsWith("林")).skip(1))
.distinct().collect(Collectors.toList()).stream().map(s -> new Actor(s)).
collect(Collectors.toList()).stream().
filter(s -> s.getName().length() == 2).count());
}
}
//演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
class Actor {
private String name;
public Actor(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Actor{" +
"name='" + name + '\'' +
'}';
}
}
1