背景

  

  Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势

Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。获取一个数据源(source)→ 数据转换→执行操作获取想要的结果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道

  

  原因

  

  一是集合类持有的所有元素都是存储在内存中的,非常巨大的集合类会占用大量的内存,而Stream的元素却是在访问的时候才被计算出来,这种“延迟计算”的特性有点类似Clojure的lazy-seq,占用内存很少。

  二是集合类的迭代逻辑是调用者负责,通常是for循环,而Stream的迭代是隐含在对Stream的各种操作中,例如map()

 特点

  

  ①不储存。数据流不是存储元素的数据结构;相反,它将元素从源数据结构、数组、生成器函数或输入/输出通道传递到计算操作的管道中。

②功能性。一个流操作产生一个结果,但不修改它的源。例如,从一个集合中过滤得到的数据流产生一个新的流,而不过滤元素,而不是从源集合中移除元素。

③懒惰寻求。许多流操作,如过滤、映射,或去除重复,可以懒洋洋地,暴露的机会,优化。例如,“寻找三个连续的元音字母的第一个字符串”不需要检查所有的输入字符串。流操作分为中间(流生产)操作和终端(价值或副作用生产)操作。中间操作总是懒惰。

④可能无界。虽然集合有一个有限的大小,流不需要。短路操作如极限(n)或findfirst()可以允许无限流计算在有限的时间内完成.

  生成(DoubleSteam、IntSteram或LongStream对象三个数值类型)

// 1. 对象
Stream stream = Stream.of("a", "b", "c");
// 2. 数组
String [] strArray = new String[] {"a", "b", "c"};
stream = Stream.of(strArray);
stream = Arrays.stream(strArray);
// 3. 集合
List<String> list = Arrays.asList(strArray);
stream = list.stream();

  

  方法

  ①filter:是一个中间操作,接受一个predicate接口类型的变量,并将所有流对象中的元素进行过滤。filter(s -> s.getState()==State.pay)

  ②map:是一个对于流对象的中间操作,通过给定的方法,它能够把流对象中的每一个元素对应到另外一个对象上。

  ③reduce:把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),返回单个的结果值,并且reduce操作每处理一个元素总是创建一个新值

  ④limit : 返回 Stream 的前面 n 个元素;skip 则是扔掉前 n 个元素

  ⑤sorted: 一个中间操作,能够返回一个排过序的流对象的视图。流对象中的元素会默认按照自然顺序进行排序,除非你自己指定一个Comparator接口来改变排序规则.

  ⑥collect: 修改现存的值

  ⑦Collectors 类的主要作用就是辅助进行各类有用的 reduction 操作

  ⑧groupingBy  按规则分组:stream().collect(Collectors.groupingBy(p->p.getState()))

  ⑨partitioningBy 是一种特殊的 groupingBy,它依照条件测试的是否两种结果来构造返回的数据结构,get(true) 和 get(false) 能即为全部的元素对象。

  Stream 有三个 match 方法,从语义上说:

  ①allMatch:Stream 中全部元素符合传入的 predicate,返回 true

  ②anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true

  ③noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true

  

  实例

 首先定义一个student类:

  

package Stream;

/**
* Created by zjc on 2018/4/9.
*/
public class Student {
public enum Sax{
FEMALE,MALE
}
private String name;
private int age;
private Sax sax;
private int height;
public Student(String name, int age,Sax sax,int height){
this.name=name;
this.age =age;
this.height = height;
this.sax = sax;
} public String getName() {
return name;
} public int getAge() {
return age;
} public Sax getSax() {
return sax;
} public int getHeight() {
return height;
} @Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sax=" + sax +
", height=" + height +
'}';
}
}

  main方法中创建实例数据:

package Stream;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.OptionalDouble;
import java.util.stream.Collectors; /**
* Created by zjc on 2018/4/9.
*/
public class test {
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student("zjc",22,Student.Sax.MALE,180),
new Student("白小",28,Student.Sax.FEMALE,170),
new Student("mengzhao",31,Student.Sax.MALE,190)
);
/**********************************************************************/
//1.输出所有性别为MALE的学生:
// 循环:
for (Student student : students){
if (student.getSax() == Student.Sax.MALE){
System.out.println(student);
}
}
//使用Stream
students.stream()
.filter(student -> student.getSax() == Student.Sax.MALE)//過濾
.forEach(System.out::println); /***********************************************************************/ /***********************************************************************/
//2.求出所有学生的平均年龄:
/**
* average方法得到一个OptionalDouble类型的值,
* 这也是Java8的新增特性,OptionalXXX类用于减少空指针异常带来的崩溃,
* 可以通过orElse方法获得其值,如果值为null,则取默认值0。
*/
OptionalDouble averageAge = students.stream()
.mapToInt(Student::getAge)//将对象映射成整形
.average();//根据整型数据求平均值
System.out.println("所有学生的平均年龄为:"+averageAge.orElse(0));
/***********************************************************************/ /***********************************************************************/
//3.输出每个学生姓名的大写形式:
List<String> names = students.stream()
.map(Student::getName) // 将Student对象映射为String(姓名)
.map(String::toUpperCase) // 将姓名转为大写
.collect(Collectors.toList()); // 生成列表
System.out.println("所有学生姓名的大写为:"+names);
/***********************************************************************/ /***********************************************************************/
//4按照年龄从小到大排序:
List<Student> sortedStudents = students.stream()
.sorted((o1, o2) -> o1.getAge() - o2.getAge())
.collect(Collectors.toList());
System.out.println("按照年龄排序后列表为:"+sortedStudents);
/***********************************************************************/ /***********************************************************************/
//5.判断是否存在名为zjc 的学生
boolean isContain = students.stream()
.anyMatch(student -> student.getName().equals("zjc"));//查询任意匹配项是否存在
System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^");
System.out.println("是否包含姓名为zjc的学生"+isContain);
/***********************************************************************/ /***********************************************************************/
//6.将所有学生按照性别分组
Map<Student.Sax,List<Student>> groupBySax = students.stream()
.collect(Collectors.groupingBy(Student::getSax));
System.out.println(groupBySax.get(Student.Sax.FEMALE));
/************************************************************************/ /************************************************************************/
//7.求出每个学生身高比例:
double sumHeight = students.stream().mapToInt(Student::getHeight).sum(); // 求出身高总和
DecimalFormat formator = new DecimalFormat("##.00"); // 保留两位小数
List<String> percentages = students.stream()
.mapToInt(Student::getHeight) // 将Student对象映射为身高整型值
.mapToDouble(value -> value / sumHeight * 100) // 求出比例
.mapToObj(per -> formator.format(per) + "%") // 组装为字符串
.collect(Collectors.toList());
System.out.println("所有学生身高比例:" + percentages);
}
}

  

  

漫漫人生路-学点Jakarta基础-Java8新特性 Stream/Lambda的更多相关文章

  1. Java8 新特性 Stream 无状态中间操作

    无状态中间操作 Java8 新特性 Stream 练习实例 中间无状态操作,可以在单个对单个的数据进行处理.比如:filter(过滤)一个元素的时候,也可以判断,比如map(映射)... 过滤 fil ...

  2. Java8 新特性 Stream() API

    新特性里面为什么要加入流Steam() 集合是Java中使用最多的API,几乎每一个Java程序都会制造和处理集合.集合对于很多程序都是必须的,但是如果一个集合进行,分组,排序,筛选,过滤...这些操 ...

  3. java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合

    java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...

  4. Java8 新特性 Stream 非短路终端操作

    非短路终端操作 Java8 新特性 Stream 练习实例 非短路终端操作,就是所有的元素都遍厉完,直到最后才结束.用来收集成自己想要的数据. 方法有: 遍厉 forEach 归约 reduce 最大 ...

  5. Java8 新特性 Stream 短路终端操作

    短路终端操作 Java8 新特性 Stream 练习实例 传入一个谓词,返回传为boolean,如果符合条件,则直接结束流. 匹配所有 allMatch 任意匹配 anymMatch 不匹配 none ...

  6. Java8 新特性学习 Lambda表达式 和 Stream 用法案例

    Java8 新特性学习 Lambda表达式 和 Stream 用法案例 学习参考文章: https://www.cnblogs.com/coprince/p/8692972.html 1.使用lamb ...

  7. Java8新特性系列-Lambda

    转载自:Java8新特性系列-Lambda – 微爱博客 Lambda Expressions in Java 8 Lambda 表达式是 Java 8 最流行的特性.它们将函数式编程概念引入 Jav ...

  8. 【Java8新特性】Lambda表达式基础语法,都在这儿了!!

    写在前面 前面积极响应读者的需求,写了两篇Java新特性的文章.有小伙伴留言说:感觉Lambda表达式很强大啊!一行代码就能够搞定那么多功能!我想学习下Lambda表达式的语法,可以吗?我的回答是:没 ...

  9. 零基础学习java------21---------动态代理,java8新特性(lambda, stream,DateApi)

    1. 动态代理 在一个方法前后加内容,最简单直观的方法就是直接在代码上加内容(如数据库中的事务),但这样写不够灵活,并且代码可维护性差,所以就需要引入动态代理 1.1 静态代理实现 在讲动态代理之前, ...

随机推荐

  1. The evolution of cluster scheduler architectures--转

    原文地址:http://www.firmament.io/blog/scheduler-architectures.html cluster schedulers are an important c ...

  2. display的几种常用取值

    display的取值有很多种,下面列出比较常用的几种取值,还有其它的少用的值没有列出来: 1.none 此元素不会被显示,并且不占据页面空间,这也是与visibility:hidden不同的地方,设置 ...

  3. CentOS7-1810 系统Samba配置说明

    Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件.SMB(Server Messages Block,信息服务块)通信协议是微软(Microsoft)和英特尔(Intel)在198 ...

  4. js实现观察者模式风格替换

    如下图,我们看到两种风格:在选择男士时,页面颜色为黑色:在选择女士时,页面颜色为粉红色. 主要可以分为两类: 下拉框 ---> 被观察者 div ---> 观察者 面向过程实现风格替换: ...

  5. ConEmu windows上的终端工具

    ConEmu Windows terminal   官网: http://conemu.github.io/        

  6. JS 中深拷贝的几种实现方法

    JS 中深拷贝的几种实现方法1.使用递归的方式实现深拷贝 //使用递归的方式实现数组.对象的深拷贝 function deepClone1(obj) { //判断拷贝的要进行深拷贝的是数组还是对象,是 ...

  7. Java基础学习总结(29)——浅谈Java中的Set、List、Map的区别

    就学习经验,浅谈Java中的Set,List,Map的区别,对JAVA的集合的理解是想对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操 ...

  8. POJ 1723 SOLDIERS

    SOLDIERS Time Limit: 1000ms Memory Limit: 10000KB This problem will be judged on PKU. Original ID: 1 ...

  9. 【转】C#中RSA加密解密和签名与验证的实现

    [转]C#中RSA加密解密和签名与验证的实现 RSA加密算法是一种非对称加密算法.在公钥加密标准和电子商业中RSA被广泛使用.RSA是1977年由罗纳德•李维斯特(Ron Rivest).阿迪•萨莫尔 ...

  10. 免费WiFi初体验——个小白的WiFi旅程

    说来羞愧,真正接触到WiFi还是在毕业后,此前自己封闭在一个人的世界,再加上外在学校的包围,我还成了个"山里"的孩子. 去年毕业了,也算是个90后,可自觉得心态过于成熟.了解外界太 ...