Java8新特性-Stream API 常用完整版

流(Stream)

1. 流的概念

流是数据渠道,用于操作数据源,所生成一种新的元素序列。集合讲的是数据,流讲的是计算,是操作

Stream是Java8中处理集合的关键抽象概念,它可以指定希望对集合的操作,可以执行复杂的查找过滤和映射数据等操作。

使用Stream API 对集合的数据进行操作,类似于SQL执行的数据库查询,也可以用来并行执行操作,其提供了一种高效且易于使用的处理数据方式

注意点:

  • Stream自身不会存储元素
  • Stream不会改变数据源对象,相反会返回产生一个持有结果的新Stream
  • Steam操作是延迟执行的,这意味着他们会等到需要结果的时候才执行

2. 流的操作步骤

三步走

2.1. 创建Stream

获取一个数据源(集合,数组),从而获取一个流
产生方式:

2.1.1 通过Collection 系列集合提供的串行流:stream()并行流: paralleStream()
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
2.1.2 通过Arrays中的静态方法stream(T[] array) 获取数组流

Arrays.stream(T[] array)的源码:

public static <T> Stream<T> stream(T[] array) {
     return stream(array, 0, array.length);
 }

用例:

Stu[] stus = new Stu[10];
Stream<Stu> stream2 = Arrays.stream(stus);
/*
  public static <T> Stream<T> stream(T[] array) {
     return stream(array, 0, array.length);
 }
 */
2.1.3 通过Stream类中的静态方法 of()

Stream.of() 源码:

//1.单参泛型of
 public static<T> Stream<T> of(T t) {
    return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}
//2.可变参数
@SafeVarargs
@SuppressWarnings("varargs") // Creating a stream from an array is safe
public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

用例:

Stream<String> stream3 = Stream.of("hxh", "aj", "hhh");
2.1.4 使用Stream类的静态方法 iterate 创建无限流

iterate方法:

Stream<T> iterate(final T seed, final UnaryOperator<T> f)

参数 seed 种子起始值UnaryOperator 函数式接口 继承Function<T,T> 此时参数类型符合返回值类型一致

用例:

//4.使用Stream类的静态方法 iterate 创建无限流
//Stream<T> iterate(final T seed, final UnaryOperator<T> f) 
//参数 seed 种子起始值,
// UnaryOperator 函数式接口 继承Function<T,T> 此时参数类型符合返回值类型一致

Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2);
//中间操作和终止操作
stream4.limit(5).forEach(System.out::println);
//0
//2
//4
//6
//8
2.1.5 使用Stream类的静态方法 generate创建无限流

generate方法参数为Supplier<T> 供给型接口

//5.使用Stream类的静态方法 generate 创建无限流
//参数为Supplier<T> 供给型接口
Stream<Double> generateStream = Stream.generate(() -> Math.random());
generateStream.limit(5).forEach(System.out::println);
//0.4762976596937549
//0.08577913333772513
//0.32149010682857515
//0.31059489250233197
//0.45181354173159927

2.2. 用Stream中间操作

一个中间操作链,用Stream API 对数据源数据进行操作处理

注意点

  • 若只有中间操作,则不会执行
  • 只有终止操作执行后,所有的中间操作一次执行,此时就称为延迟加载或者惰性求值

验证是否是延迟加载:

@Test
public  void test2(){
    //取age>30的Stu元素
    //若只有中间操作,则不会执行
    Stream<Stu> stuStream = stuList.stream().filter((i) -> {
        System.out.println("验证是否是延迟加载");
        return  i.getAge() > 40;
    });
    //此时只有中间操作,无终止操作,无结果,控制台无输出

}

此时只有中间操作,无终止操作无结果,控制台无输出

此时加上终止操作后:

@Test
public  void test2(){
    //取age>30的Stu元素
    //若只有中间操作,则不会执行
    Stream<Stu> stuStream = stuList.stream().filter((i) -> {
        System.out.println("验证是否是延迟加载");
        return  i.getAge() > 40;
    });
    //终止操作 执行后,所有的中间操作一次执行,此时就称为延迟加载或者惰性求值
    stuStream.forEach(System.out::println);
}

此时结果为:

验证是否是延迟加载
验证是否是延迟加载
验证是否是延迟加载
验证是否是延迟加载
Stu{
  
  id=4, name='cc', age=42}
验证是否是延迟加载
Stu{
  
  id=5, name='dd', age=52}

结论:若只有中间操作,则不会执行中间操作。终止操作 执行后,所有的中间操作一次执行。最后流中只有经过操作过滤后的元素。

2.2.1 筛选与切片

迭代:
- 内部迭代:迭代过程操作由Stream API 内部自主完成,无需自行再次编写。
- 外部迭代:由程序编写人员自己通过一些迭代方法进行的迭代操作。

2.2.1.1 filter-过滤

Stream<T> filter(Predicate<? super T> predicate)
断言型接口参数 即条件判断过滤

用例:
先创建一个Stu类List集合

List<Stu> stuList = Arrays.asList(
        new Stu(1,"hh",22),
        new Stu(2,"aa",22),
        new Stu(3,"bb",32),
        new Stu(4,"cc",42),
        new Stu(5,"dd",52)
);

filter过滤实现:


                
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值