java8新特性 -- Stream

Java8中有两个非常有名的改进,一个是Lambda表达式,一个是Stream。而新增了stream流的特性,能够让用户以函数式的方式、更为简单的操纵集合等数据结构,并实现了用户无感知的并行计算。

Stream介绍

Stream是一个流,在Java.util.Stream包路径下,他的主要作用就是对集合数据进行查找过滤等操作。通俗解释就是一种高效且易用的数据处理方式。大数据领域也有一个Steam实时流计算框架,不过和这个可不一样。别搞混了。

Stream和Collection的区别就是:Collection只是负责存储数据,不对数据做其他处理,主要是和内存打交道。但是Stream主要是负责计算数据的,主要是和CPU打交道。

stream优点:
举个例子: 有一个List列表,我们需要获得年龄为70岁的前10个Person的姓名。
过程式的解决方案:
  稍加思考,我们很快就写出了一个过程式的解决方案(伪代码):

List<Person> personList = fromDB(); // 获得List<Person>
int limit = 10; // 限制条件
List<String> nameList = new ArrayList(); // 收集的姓名集合
for(Person personItem : personList){
    if(personItem.age == 70){ // 满足条件
        nameList.add(personItem.name); // 加入姓名集合
        if(nameList.size() >= 10){ // 判断是否超过限制
            break;
        }
    }
}
return nameList;

函数式stream解决方案:

下面我们给出一种基于stream流的解决方案(伪代码):

List<Person> personList = fromDB(); // 获得List<Person>
List<String> nameList = personList.stream()
      .filter(item->item.age == 70) // 过滤条件
      .limit(10)    // limit限制条件
      .map(item->item.name) // 获得姓名
      .collect(Collector.toList()); // 转化为list

return nameList;

两种方案的不同之处:
  从函数式的角度上看,过程式的代码实现将收集元素、循环迭代、各种逻辑判断耦合在一起,暴露了太多细节。当未来需求变动和变得更加复杂的情况下,过程式的代码将变得难以理解和维护(需要控制台打印出 年龄为70岁的前10个Person中,姓王的Person的名称)。
  函数式的解决方案解开了代码细节和业务逻辑的耦合,类似于sql语句,表达的是"要做什么"而不是"如何去做",使程序员可以更加专注于业务逻辑,写出易于理解和维护的代码。

Stream 特性:

无存储。Stream 不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java 容器或 I/O channel 等。
为函数式编程而生。对 Stream 的任何修改都不会修改背后的数据源,比如对 Stream 执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新 Stream。
惰式执行。Stream 上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
可消费性。Stream 只能被 " 消费 " 一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。

Stream操作步骤

Stream执行流程很简单,主要有三个:
1、创建一个Stream:从一个数据源,如集合、数组中获取流
2、使用Stream操作数据:一个操作的中间链,对数据源的数据进行操作
3、终止Stream:一个终止操作,执行中间操作链,并产生结果
要注意的是,对流的操作完成后需要进行关闭操作

创建Stream

public static void test1() {
     List <Student> students =StudentData.getStudents();
     //第一种:返回一个顺序流
     Stream  <Student> stream = students.stream();
     //第二种:返回一个并行流
     Stream  <Student> stream1 = students.parallelStream();
}
//通过一个数组创建stream
 public static void test2() {
   //获取一个整形stream
   int[]arr = {1, 34, 2, 54, 56, 34};
   IntStream stream = Arrays.stream(arr);
 }
//通过Stream.of
public static void test3() {
   Stream <String> stringStream = Stream.of("1", "4", "34", "23");
   Stream <Student> studentStream = Stream.of(
       new Student(1, "小白", 23, 89.5),
       newStudent(2, "小蔡", 22, 90.9)
   );
}
//创建无限流
public static void test4() {
   //每隔5个数取一个,从0开始,此时就会无限循环
   Stream<Integer> iterate = Stream.iterate(0,t -> t + 5);
   //取出一个随机数
   Stream<Double> generate = Stream.generate(Math::random);
}
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值