Stream
简介
Stream(流)是数据渠道,用于操作数据源(集合、数组等),生成元素序列。换言之,集合是存储数据的容器,流使用操作这些数据的
Stream可以对集合进行非常复杂的查找、过滤、映射数据等操作,类似于SQL执行数据库查询。Stream提供了一种高效且易于使用的处理数据的方式
注意:
- Stream不会存储数据
- Stream不会改变源数据,通过一系列操作数据源会返回一个持有结果的新Stream
- Stream操作是延迟执行的,意味着流会等到需要结果的时候才执行
执行步骤
- 创建Stream:通过数据源(集合、数组等)获取一个Stream
- 中间操作:中间操作链,对源数据的数据进行处理
- 终止操作:执行中间操作,并产生结果
创建Stream
public class Test1 {
@Test
public void test01() {
//方式一:通过Collection接口提供的stream()-串行流或parallelStream()-并行流 获取流对象
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
//方式二:通过Arrays的静态方法stream()获取流对象
String[] strs = new String[10];
Stream<String> stream2 = Arrays.stream(strs);
//方式三:通过Stream的静态方法of()获取流对象
Stream<String> stream3 = Stream.of("aaa","bbb","ccc");
//方式四:创建无限流
//iterate()迭代
Stream<Integer> stream4 = Stream.iterate(1, (x)->x+=100);
stream4.limit(3).forEach(System.out::println);
//方式五:创建无限流
//generate()生成
Stream<Double> stream5 = Stream.generate(()->Math.random());
stream5.limit(3).forEach(System.out::println);
}
}
注意:多个中间操作可以连接成一个流水线,除非流水线触终止操作,否则中间操作不会执行任何的处理,而在终止操作时一次性全部处理,称为惰性求值/延迟加载
中间操作 - 筛选与切片
方法 | 描述 |
---|---|
filter(Predicate p) | 从流中排除元素 |
limit(long maxSize) | 设置限制数据条数 |
skip(long n) | 跳过元素,返回跳过n个元素的流,若流中不满足n个元素则返回空流。与limit()互补 |
distinct() | 筛选,流通过元素对象的hashCode()和equals()方法去除重复元素 |
如果没有终止操作,中间操作就不会被调用,终止操作时一次性全部处理,这种称为惰性求值/延迟加载
public class Test1 {
List<Student> stuList = Arrays.asList(
new Student("张三", 28, 4800,Course.JAVA),
new Student("李四", 36, 7200,Course.JAVA),
new Student("王五", 19, 9600,Course.HTML),
new Student("赵六", 42, 6100,Course.HTML),
new Student("孙七", 23, 9600,Course.PYTHON),
new Student("吴八", 31, 3000,Course.PYTHON),
new Student("李四", 36, 7200,Course.JAVA));
@Test
public void test01() {
//需求1:过滤掉小于5000的学生对象
Stream<Student> stream = stuList.stream().filter((x)-> {
System.out.println("中间操作");
return x.getSalary()>5000;
});
//迭代输出流里的数据就等同于终止操作
//迭代功能在forEach()中完成,称为内部迭代(集合使用iterator()称为外部迭代)
stream.forEach(System.out::println);
}
@Test
public void test02() {
//需求2:过滤掉小于5000的学生对象,并显示3条
//注意:因为限制了数据条数,所以满足数据条数后,后续的操作就不再运行了,效率就提高了
Stream<Student> stream = stuList.stream().filter((x)-> {
System.out.println("短路");
return x.getSalary()>5000;
}).limit(3);
//迭代输出流里的数据就等同于终止操作
//迭代功能在forEach()中完成,称为内部迭代(集合使用iterator()称为外部迭代)
stream.forEach(System.out::println);
}
@Test
public void test03() {
//需求3:过滤掉小于5000的学生对象,并跳过第1个学生对象
Stream<Student> stream = stuList.stream().
filter((x)-> x.getSalary()>5000).
skip(1);
//迭代输出流里的数据就等同于终止操作
//迭代功能在forEach()中完成,称为内部迭代(集合使用iterator()称为外部迭代)
stream.forEach(System.out::println);
}
@Test
public void test04() {
//需求4:过滤掉小于5000的学生对象,并筛选掉重复元素
//Stream底层通过元素对象(Student对象)的hashCode()和equals()方法去除重复元素
Stream<Student> stream = stuList.stream().
filter((x)-> x.getSalary()>5000).
distinct();
//迭代输出流里的数据就等同于终止操作
//迭代功能在forEach()中完成,称为内部迭代(集合使用iterator()称为外部迭代)
stream.forEach(System.out::</