Stream基本概念
流是数据渠道,用于操作数据源,所生成一种新的元素序列。集合讲的是数据,流讲的是计算,是操作。使用Stream API 对集合的数据进行操作,类似于SQL执行的数据库查询,也可以用来并行执行操作,其提供了一种高效且易于使用的处理数据方式。
- Stream不会改变数据源对象,相反会返回产生一个持有结果的新Stream。
- Steam操作是延迟执行的,这意味着他们会等到需要结果的时候才执行。
- 一个流只能使用一次,使用后就会被关闭。
创建Stream
方法一
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
方法二
Stu[] stus = new Stu[10];
Stream<Stu> stream2 = Arrays.stream(stus);
方法三
Stream<String> stream3 = Stream.of("hxh", "aj", "hhh");
Stream中间操作
Stream是一个中间操作,如果没有被使用的话,将不会执行。
可以进行一系列的Stream操作,在需要结果时统一执行。
代码示例:
- 以下通用实体,创建一个Animal的list
@Data
public class Animal {
String name;
String type;
Integer age;
public Animal(){}
public Animal(String name,String type,Integer age){
this.name = name;
this.type = type;
this.age = age;
}
public static List<Animal> getAnimals(){
List<Animal> animals = new ArrayList<>();
animals.add(new Animal("田园犬","犬科",5));
animals.add(new Animal("猎犬","犬科",15));
animals.add(new Animal("哈士奇","犬科",6));
animals.add(new Animal("咖啡猫","猫科",33));
animals.add(new Animal("小猫","猫科",4));
animals.add(new Animal("大猫","猫科",18));
return animals;
}
}
- 验证延迟加载(中间操作)
public static void main(String[] args) {
//创建一个list
List<Animal> animals = Animal.getAnimals();
//选择年龄大于10的动物(中间操作)
Stream<Animal> s = animals.stream().filter(animal -> {
System.out.println("验证延迟加载");
return animal.getAge()>10;
});
//将上一步生成的流再次筛选年龄大于20的动物(中间操作)
//断点到此处,控制台无打印
Stream<Animal> s1 = s.filter(animal -> animal.getAge()>20);
//断点到此处,控制打印
//终止操作执行后,所有的中间操作一次执行,此时就称为延迟加载或者惰性求值
List<Animal> l = s1.collect(Collectors.toList());
l.forEach(e-> System.out.println(e));
}
筛选
filter(过滤器)
功能:根据条件过滤列表数据
代码:
List<Animal> animals = Animal.getAnimals();
List<Animal> list = animals.stream().filter(animal -> animal.getAge() > 10).collect(Collectors.toList());
list.forEach(l-> System.out.println(l.getName()+":"+l.getAge()));
输出结果:
猎犬:15
咖啡猫:33
大猫:18
limit(限定元素数量)
功能:通过截断流,使流中元素个数不超过指定数量
代码:
List<Animal> animals = Animal.getAnimals();
List<Animal> list = animals.stream().filter(animal -> animal.getAge() > 10).limit(1).collect(Collectors.toList());
list.forEach(l-> System.out.println(l.getName()+":"+l.getAge()));
输出结果:
猎犬:15
skip(跳过元素)
功能:返回一个跳过前n个元素的流,若流中元素不足n个,则返回一个空流
代码:
List<Animal> animals = Animal.getAnimals();
List<Animal> list = animals.stream().filter(animal -> animal.getAge() > 10).skip(1).collect(Collectors.toList());
list.forEach(l-> System.out.println(l.getName()+":"+l.getAge()));
输出结果:
咖啡猫:33
大猫:18
distinct(去重)
功能:通过截断流,使流中元素个数不超过指定数量
代码:
List<Animal> animals = Animal.getAnimals();
//在列表中插入同样的一个田园犬
animals.add(new Animal("田园犬","犬科",5));
//先筛选出田园犬的列表
animals = animals.stream().filter(animal -> animal.getName().equals("田园犬")).collect(Collectors.toList());
//循环输出
animals.forEach(l-> System.out.println(l.getName()+":"+l.getAge()));
System.out.println("-------------");
//去重操作
List<Animal> list = animals.stream().distinct().collect(Collectors.toList());
list.forEach(l-> System.out.println(l.getName()+":"+l.getAge()));
输出结果:
田园犬:5
田园犬:5
-------------
田园犬:5