一.什么是 Stream?
流是数据渠道,用于操作数据源(集合,数组等)所生成的元素序列
二.流(Stream)操作的三个步骤
1.创建Stream
一个数据源(集合、数组..)
//1.集合获取流
List list = new ArrayList();
Stream stream = list.stream();
//2.通过Arrays中的静态方法stream()获取数组流
String[] array = new String[10];
Stream stream1 = Arrays.stream(array);
//3.通过Stream类中的静态方法 of()
Stream stream2 = Stream.of("q", "w", "e");
//4.创建无限流
//迭代
Stream stream3 = Stream.iterate(0, (x) -> x * x);
//生成
Stream stream4 = Stream.generate(Math::random);
2.中间操作
一个中间操作链,对数组进行处理(limit 、filter、map等等)
//一个实体类
public class User {
private String name;
private int age;
private String sex;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age &&
Objects.equals(name, user.name) &&
Objects.equals(sex, user.sex);
}
@Override
public int hashCode() {
return Objects.hash(name, age, sex);
}
//......省略get/set方法、构造方法、toString方法....
}
- 筛选与切片
filter:接收lamdba,从流中排除某些元素
limit(n):截断流,包含n个数量的元素的流
skip(n):跳过流元素,返回一个截掉前n个的流
distinct:筛选,通过流生成元素的hashCode()和equals()去除重复元素
List users = new ArrayList();
users.add(new User("小明", 12, "男"));
users.add(new User("小花", 21, "男"));
users.add(new User("小花", 21, "男"));
users.add(new User("小白", 15, "男"));
users.add(new User("小黑", 8, "男"));
Stream stream = users.stream()
.filter(item -> item.getAge() > 10);
Stream stream1 = users.stream()
.filter(item -> item.getAge() > 10).limit(2);
Stream stream2 = users.stream()
.filter(item -> item.getAge() > 10)
.skip(2);
Stream stream3 = users.stream()
.filter(item -> item.getAge() > 10)
.distinct();
//终止操作
System.out.println("stream");
stream.forEach(System.out::println);
System.out.println("stream1");
stream1.forEach(System.out::println);
System.out.println("stream2");
stream2.forEach(System.out::println);
System.out.println("stream3");
stream3.forEach(System.out::println);
- 映射
map:接收Lamdba,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素,并将其映射成新的元素
List users = new ArrayList();
users.add(new User("小明",12,"男"));
users.add(new User("小花",21,"男"));
users.add(new User("小黑",8,"男"));
users.stream()
.map(User::getName)
.forEach(System.out::println);
- 排序
sorted():自然排序(Comparable)
sorted(Comparator comparator):定制排序(Comparator)
List users = new ArrayList();
users.add(new User("小花",21,"男"));
users.add(new User("小明",12,"男"));
users.add(new User("小黑",8,"男"));
users.stream()
.map(User::getAge)
.sorted()
.forEach(System.out::println);
users.stream()
.sorted(Comparator.comparing(User::getName))
.forEach(System.out::println);
3.终止操作
一个终止操作,执行中间操作链,产生结结果
allMatch:检查是否匹配所有元素
anyMatch:检查是否至少匹配一个元素
noneMatch:检查是否没有匹配元素
findFirst: 返回第一个元素
findAny:返回当前流中的任意元素
count:返回流中元素的总个数
max:返回流中最大值
min:返回流中最小值
List users = new ArrayList();
users.add(new User("小明", 12, "男"));
users.add(new User("小花", 21, "男"));
users.add(new User("小白", 15, "男"));
users.add(new User("小黑", 8, "男"));
boolean b = users.stream()
.allMatch(e -> ("小明").equals(e.getName()));
boolean b1 = users.stream()
.anyMatch(e -> ("小明").equals(e.getName()));
boolean b2 = users.stream()
.noneMatch(e -> ("ss").equals(e.getName()));
Optional first = users.stream()
.findFirst();
long count = users.stream()
.count();
Optional max = users.stream()
.max(Comparator.comparingInt(User::getAge));
Optional min = users.stream()
.min(Comparator.comparingInt(User::getAge));
- 归约
reduce() :将流中的元素反复结合起来,得到一个值。
List list = Arrays.asList(2,3,5,6);
Integer num = list.stream()
.reduce(2,(x,y) -> x+y);
List users = new ArrayList();
users.add(new User("小明", 12, "男"));
users.add(new User("小花", 21, "男"));
users.add(new User("小白", 15, "男"));
users.add(new User("小黑", 8, "男"));
Optional reduce = users.stream().map(User::getAge)
.reduce(Integer::sum);
- 收集
collect :将流转换为其他形式。接收一个Collector接收的实现,由于给Stream中的元素做汇总的方法
List users = new ArrayList();
users.add(new User("小明", 12, "男"));
users.add(new User("小花", 21, "男"));
users.add(new User("小白", 15, "男"));
users.add(new User("小黑", 8, "男"));
List collect = users.stream()
.map(User::getName)
.collect(Collectors.toList());
collect.forEach(System.out::println);
Set set = users.stream()
.map(User::getName)
.collect(Collectors.toSet());
set.forEach(System.out::println);
注意:
- Stream 自己不会存储元素。
- Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
- Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。