JDK8新特性-stream流

介绍

Stream流的出现,得益于 Lambda 多带来的 “函数式编程” , 用于解决已有集合类库的遍历的弊端

JDK8之前的集合遍历操作:

public class fun1 {
    List<String> list = new ArrayList<>();
    
    list.add("1");
    list.add("2");
    
    for(String item : list) {
        System.out.println(name);
    }
}

当我们需要对集合的元素进行操作的时候,总是需要循环,再循环。循环只是做业务的方式,而不是业务目的,Lambda 的衍生物 Stream 能给我们带来什么优雅的写法?

循环遍历的弊端:

JDK8 之前的 Lambda 专注于 做什么,而不是怎么做。但是 for 循环的语法关注于 怎么做,循环体才是做什么。所以有没有一种优雅写法可以把怎么做取代掉,专注于做什么?

Stream 优雅写法

借助 JDK8 的 Stream API , 关注于做什么,不关注怎么做

public class fun1 {
    List<String> list = new ArrayList<>();
    
    list.add("1");
    list.add("2");
    
    list.stream()
        .filter(name -> name.startWith('张')) // 过滤1
        .filter(name -> name.length() == 3) // 过滤2
        .forEach(name -> System.out.println(name)) // 输出
}

流式思想概述

当需要对多个元素进行操作,特别式多步操作的时候,考虑到性能和便利性,我们应当首先拼好一个函数模型步骤方案,然后按照方案去执行它
在这里插入图片描述

这张图展示了过滤,映射,跳过,技术等多步操作,这是一个集合元素的处理方案,而方案就是一种"函数模型" ,图的每一个方框就是一个 “流”,调用指定的方法,可以从一个流模型转到另一个流模型,而最右侧的数字3 就是最终结果

这里的 filtermap, skip 都是对函数模型进行操作,集合元素并没有真正的被处理,只有当终结方法 count 执行的时候,整个模型才会按照指定策略执行操作,这得益于 Lambda 的延迟执行特性

获取流

java.util.stream.Stream<T> 是 Java8 新增的最常用的流接口(并不是一个函数式接口)

获取流有两种方式:

  • 方式一: 所有的 collection 集合都可以通过 stream 默认方法获取流
  • 方式二: Stream 接口的静态方法 of 可以获取数组对应的流

根据 Collection 获取流

由于,java.util.Collection 接口中加入了 default 方法 stream 用来获取流,所以其所有的实现类均可以获取流

//把集合转换为Stream流
List<String> list = new ArrayList<>();
Stream<String> streaml = list.stream(); .
    
Set<string> set = new HashSet<>();
Stream<String> stream2 = set.stream();

Map<String,String> map = new HashMap<>();
//获取键,存储到一个Set集合中
Set<String> keySet = map. keySet();
Stream<String> stream3 = keySet.stream();

//获取值,存储到一个Collection集合中
Collection<String> values = map.values();
Stream<String> stream4 = values.stream( );

//获取键值对<键与值的映射关系entrySet)
Set<Map.Entry<string, String>> entries = map. entrySet();
Stream<Map.Entry<string, String>> streams = entries.stream();

使用 of 获取流

//数组转为Stream流
Stream<Integer> stream6 = Stream.of(1,2,3,4,5);
// 可变参数可以传递数组
Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream7 = Stream.of(arr);

常用方法

在这里插入图片描述

流模型的操作很丰富,这里介绍-些常用的API。 这些方法可以被分成两种:
延迟方法:返回值类型仍然是 stream 接口自身类型的方法,因此支持链式调用。( 除了终结方法外,其余方
法均为延迟方法。)
终结方法:返回值类型不再是 Stream 接口自身类型的方法,因此不再支持类似 stringBuilder 那样的链
式调用。本小节中,终结方法包括 count 和 forEach 方法。
备注:本小节之外的更多方法,请自行参考API文档。

Stream 流属于 ”管道流“,只能被消费一次。意思是:第一个 Stream 流调用完毕后,数据就会流转到下一个 Stream 上,而这时第一个 Stream 流已经使用完毕,即关闭了,所以第一个Stream流就不能再调用方法了。

逐一处理:forEach

作用:用于遍历流中的数据,由于属于终结方法,遍历之后就不能继续调用 Stream 流的其他方法

// 获取一个 Stream 流
Stream<String> stream7 = Stream.of("a","b","c");
// 对 Stream 流中的数据进行遍历
stream7.forEach( (name) -> {
    System.out.println(name);
});

过滤:filter

作用:通过 filter 方法将流转为另一个子集流

// 获取一个 Stream 流
Stream<String> stream1 = Stream.of("a","b","c");

// 对 stream 流进行过滤
Stream<String> stream2 = stream1.filter(item -> {
    return item.startsWith('7');
});

stream2.forEach(item -> System.out.println(item));

映射:map

作用:将流中的元素映射到另一个流中

// 获取一个 Stream 流
Stream<String> stream1 = Stream.of("1","2","3");

// 使用 map 方法,对流进行映射
Stream<Integer> stream2 = stream1.map(s -> {
    return Integer.parseInt(s);
});

stream2.forEach(item -> System.out.println(item));

个数:count

作用:用于统计 Stream 流中元素的个数

返回值:long 类型的整数

// 获取一个 Stream 流
Stream<String> stream1 = Stream.of("1","2","3");

// 使用 map 方法,对流进行映射
long count = stream1.count();

截取:limit

作用:对流进行截取,只取前 n 个

参数:long 类型

// 获取一个 Stream 流
Stream<String> stream1 = Stream.of("1","2","3");

// 使用 limit 方法,对流进行截取
Stream<String> result = stream1.limit(2);

跳过:skip

作用:用于跳过前几个

参数:long 型

// 获取一个 Stream 流
Stream<String> stream1 = Stream.of("1","2","3");

// 使用 limit 方法,对流进行截取
Stream<String> result = stream1.skip(2);

拼接:contact

作用:Stream 流的静态方法,用于将两个流合并为一个流

// 获取一个 Stream 流
Stream<String> stream1 = Stream.of("1","2","3");
// 获取一个 Stream 流
Stream<String> stream2 = Stream.of("1","2","3");

Stream<String> result = Stream.contach(stream1,stream2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值