Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及 java.util.stream 包。 流(stream)就如同迭代器(iterator),但附加了许多额外的功能。

Lambda表达式的语法

基本语法:

(parameters) -> expression

或:

(parameters) ->{ statements; }

基本lambda例子:集合的forEach(()->{})

// 使用 lambda 表达式以及函数操作(functional operation)
players.forEach((player) -> System.out.print(player + "; ")); // 在 Java 8 中使用双冒号操作符(double colon operator)
players.forEach(System.out::println);

使用lambdas 来实现 Runnable接口 的示例:

// 1.1使用匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
}).start(); // 1.2使用 lambda expression
new Thread(() -> System.out.println("Hello world !")).start(); // 2.1使用匿名内部类
Runnable race1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
}; // 2.2使用 lambda expression
Runnable race2 = () -> System.out.println("Hello world !"); // 直接调用 run 方法(没开新线程哦!)
race1.run();
race2.run();

使用Lambdas和Streams

Stream是对集合的包装,通常和lambda一起使用。 使用lambdas可以支持许多操作,如 map, filter, limit, sorted, count, min, max, sum, collect 等等。

System.out.println("给程序员加薪 5% :");
Consumer<Person> giveRaise = e -> e.setSalary(e.getSalary() / 100 * 5 + e.getSalary());
javaProgrammers.forEach(giveRaise);
phpProgrammers.forEach(giveRaise);

Consumer:接口,Consumer<T>:Represents an operation that accepts a single input argument and returns no result.

使用过滤器:

System.out.println("下面是月薪超过 $1,400 的PHP程序员:")
phpProgrammers.stream()
.filter((p) -> (p.getSalary() > 1400))
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));

支持多重过滤:

filter
(Predicate<? super T> predicate)

return:Stream<T>

作用:Returns a stream consisting of the elements of this stream that match the given predicate.

// 定义 filters
Predicate<Person> ageFilter = (p) -> (p.getAge() > 25);
Predicate<Person> salaryFilter = (p) -> (p.getSalary() > 1400);
Predicate<Person> genderFilter = (p) -> ("female".equals(p.getGender())); System.out.println("下面是年龄大于 24岁且月薪在$1,400以上的女PHP程序员:");
phpProgrammers.stream()
.filter(ageFilter)
.filter(salaryFilter)
.filter(genderFilter)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
// 重用filters
System.out.println("年龄大于 24岁的女性 Java programmers:");
javaProgrammers.stream()
.filter(ageFilter)
.filter(genderFilter)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));

limit(long maxSize)

return:Stream<T>

作用:Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.

System.out.println("最前面的3个 Java programmers:");
javaProgrammers.stream()
.limit(3)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName())); System.out.println("最前面的3个女性 Java programmers:");
javaProgrammers.stream()
.filter(genderFilter)
.limit(3)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));

collect:是一个终端操作,它接收的参数是将流中的元素累积到汇总结果的各种方式(称为收集器)

System.out.println("根据 name 排序,并显示前5个 Java programmers:");
List<Person> sortedJavaProgrammers = javaProgrammers
.stream()
.sorted((p, p2) -> (p.getFirstName().compareTo(p2.getFirstName())))
.limit(5)
.collect(toList()); //获取前5个保存到List中
sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));
System.out.println("根据 salary 排序 Java programmers:");
sortedJavaProgrammers = javaProgrammers
.stream()
.sorted( (p, p2) -> (p.getSalary() - p2.getSalary()) )
.collect( toList() );
sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));

min和max方法

System.out.println("工资最低的 Java programmer:");
Person pers = javaProgrammers
.stream()
.min((p1, p2) -> (p1.getSalary() - p2.getSalary())) //返回值:Optional<T>
.get(); //A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
System.out.printf("Name: %s %s; Salary: $%,d.", pers.getFirstName(), pers.getLastName(), pers.getSalary()); System.out.println("工资最高的 Java programmer:");
Person person = javaProgrammers
.stream()
.max((p, p2) -> (p.getSalary() - p2.getSalary()))
.get();
System.out.printf("Name: %s %s; Salary: $%,d.", person.getFirstName(), person.getLastName(), person.getSalary());

结合 map 方法,我们可以使用 collect 方法来将我们的结果集放到一个字符串,一个 Set 或一个TreeSet中:

System.out.println("将 PHP programmers 的 first name 拼接成字符串:");
String phpDevelopers = phpProgrammers
.stream()
.map(Person::getFirstName)
.collect(joining(" ; ")); // 在进一步的操作中可以作为标记(token) System.out.println("将 Java programmers 的 first name 存放到 Set:");
Set<String> javaDevFirstName = javaProgrammers
.stream()
.map(Person::getFirstName)
.collect(toSet()); System.out.println("将 Java programmers 的 first name 存放到 TreeSet:");
TreeSet<String> javaDevLastName = javaProgrammers
.stream()
.map(Person::getLastName)
.collect(toCollection(TreeSet::new));

Streams 还可以是并行的(parallel)。

System.out.println("计算付给 Java programmers 的所有money:");
int totalSalary = javaProgrammers
.parallelStream()
.mapToInt(p -> p.getSalary())
.sum();

我们可以使用summaryStatistics方法获得stream 中元素的各种汇总数据。 接下来,我们可以访问这些方法,比如getMax, getMin, getSum或getAverage:

//计算 count, min, max, sum, and average for numbers
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
IntSummaryStatistics stats = numbers
.stream()
.mapToInt((x) -> x)
.summaryStatistics();
System.out.println("List中最大的数字 : " + stats.getMax());
System.out.println("List中最小的数字 : " + stats.getMin());
System.out.println("所有数字的总和 : " + stats.getSum());
System.out.println("所有数字的平均值 : " + stats.getAverage());

附:.collect()参数

工厂方法

返回类型

用于

toList

List<T>

把流中所有元素收集到List中

示例:List<Menu> menus=Menu.getMenus.stream().collect(Collector.toList())

toSet

Set<T>

把流中所有元素收集到Set中,删除重复项

示例:Set<Menu> menus=Menu.getMenus.stream().collect(Collector.toSet())

toCollection

Collection<T>

把流中所有元素收集到给定的供应源创建的集合中

示例:ArrayList<Menu> menus=Menu.getMenus.stream().collect(Collector.toCollection(ArrayList::new))

Counting

Long

计算流中元素个数

示例:Long count=Menu.getMenus.stream().collect(counting);

SummingInt

Integer

对流中元素的一个整数属性求和

示例:Integer count=Menu.getMenus.stream().collect(summingInt(Menu::getCalories))

averagingInt

Double

计算流中元素integer属性的平均值

示例:Double averaging=Menu.getMenus.stream().collect(averagingInt(Menu::getCalories))

Joining

String

连接流中每个元素的toString方法生成的字符串

示例:String name=Menu.getMenus.stream().map(Menu::getName).collect(joining(“, ”))

maxBy

Optional<T>

一个包裹了流中按照给定比较器选出的最大元素的optional

如果为空返回的是Optional.empty()

示例:Optional<Menu> fattest=Menu.getMenus.stream().collect(maxBy(Menu::getCalories))

minBy

Optional<T>

一个包裹了流中按照给定比较器选出的最大元素的optional

如果为空返回的是Optional.empty()

示例: Optional<Menu> lessest=Menu.getMenus.stream().collect(minBy(Menu::getCalories))

Reducing

归约操作产生的类型

从一个作为累加器的初始值开始,利用binaryOperator与流中的元素逐个结合,从而将流归约为单个值

示例:int count=Menu.getMenus.stream().collect(reducing(0,Menu::getCalories,Integer::sum));

collectingAndThen

转换函数返回的类型

包裹另一个转换器,对其结果应用转换函数

示例:Int count=Menu.getMenus.stream().collect(collectingAndThen(toList(),List::size))

groupingBy

Map<K,List<T>>

根据流中元素的某个值对流中的元素进行分组,并将属性值做为结果map的键

示例:Map<Type,List<Menu>> menuType=Menu.getMenus.stream().collect(groupingby(Menu::getType))

partitioningBy

Map<Boolean,List<T>>

根据流中每个元素应用谓语的结果来对项目进行分区

示例:Map<Boolean,List<Menu>> menuType=Menu.getMenus.stream().collect(partitioningBy(Menu::isType));

Java8必知必会的更多相关文章

  1. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  2. 读书笔记--SQL必知必会--建立练习环境

    书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL in 10 Minutes - Fourth Edition> MyS ...

  3. 读书笔记--SQL必知必会12--联结表

    12.1 联结 联结(join),利用SQL的SELECT在数据查询的执行中联结表. 12.1.1 关系表 关系数据库中,关系表的设计是把信息分解成多个表,一类数据一个表,各表通过某些共同的值互相关联 ...

  4. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  5. 《MySQL 必知必会》读书总结

    这是 <MySQL 必知必会> 的读书总结.也是自己整理的常用操作的参考手册. 使用 MySQL 连接到 MySQL shell>mysql -u root -p Enter pas ...

  6. 《SQL必知必会》学习笔记(一)

    这两天看了<SQL必知必会>第四版这本书,并照着书上做了不少实验,也对以前的概念有得新的认识,也发现以前自己有得地方理解错了.我采用的数据库是SQL Server2012.数据库中有一张比 ...

  7. SQL 必知必会

    本文介绍基本的 SQL 语句,包括查询.过滤.排序.分组.联结.视图.插入数据.创建操纵表等.入门系列,不足颇多,望诸君指点. 注意本文某些例子只能在特定的DBMS中实现(有的已标明,有的未标明),不 ...

  8. .NET程序员项目开发必知必会—Dev环境中的集成测试用例执行时上下文环境检查(实战)

    Microsoft.NET 解决方案,项目开发必知必会. 从这篇文章开始我将分享一系列我认为在实际工作中很有必要的一些.NET项目开发的核心技术点,所以我称为必知必会.尽管这一系列是使用.NET/C# ...

  9. 0005 《SQL必知必会》笔记01-SELECT语句

    1.SELECT基本语句: SELECT 字段名1,···,字段名n FROM 表名 2.检索所有字段,用"*"替换字段名,这会导致效率低下 SELECT * FROM 表名; 3 ...

  10. 2015 前端[JS]工程师必知必会

    2015 前端[JS]工程师必知必会 本文摘自:http://zhuanlan.zhihu.com/FrontendMagazine/20002850 ,因为好东东西暂时没看懂,所以暂时保留下来,供以 ...

随机推荐

  1. 每天一点点之vue框架开发 - 引入Jquery

    1. 安装jquery npm install jquery --save-dev 2.在build/webpack.base.conf.js中添加如下内容 var webpack = require ...

  2. 洛谷 P2370 yyy2015c01的U盘

    题目传送门 解题思路: 先将每个文件按照占空间从小到大排序,然后跑背包,当到了某一个文件时,价值够了,那么当前文件的体积就是答案. 其实本题是可以二分答案的,但是写挂了... AC代码: #inclu ...

  3. css常用技巧1

    css绘制三角形 <style> .triangle-box{ margin: 50px auto; height: 300px; width: 500px; box-shadow: 1p ...

  4. apache2+django+virtualenv 服务器部署实战

    目录 基本配置 配置python环境 安装 python.pip 安装 virtualenv 配置python虚拟环境 配置 apache2 安装 apache2 安装 mod-wsgi 服务 部署d ...

  5. C3P0模板

    1.创建c3p0-config.xml配置文件放在src下 <?xml version="1.0" encoding="UTF-8"?> <c ...

  6. POJ 1562:Oil Deposits

    Oil Deposits Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14462   Accepted: 7875 Des ...

  7. 大数据攻城狮之进阶技能-使用Git上传自己的项目至GitHub仓库

    在开始讲解之前我们默认已经存在仓库和安装Git,没有下载的可以去https://git-scm.com/ Git官方网站下载或者是私聊博主. 下面我们说一说Git的使用,比如说如何生成密钥,连接远程仓 ...

  8. 68.ORM查询条件:date,time,year,week_day等

    1. date: 首先查看数据库中article表的信息,由表中的create_time字段可以看出时间为2020.2.5 打印出查询的结果: <QuerySet []>:但是查询的结果为 ...

  9. dirname() 函数返回路径中的目录部分。

    定义和用法 dirname() 函数返回路径中的目录部分. 语法 dirname(path) 参数 描述 path 必需.规定要检查的路径. 说明 path 参数是一个包含有指向一个文件的全路径的字符 ...

  10. sping中 各种注解——@SuppressWarnings注解用法

    @SuppressWarnings注解用法 @SuppressWarnings注解主要用在取消一些编译器产生的警告对代码左侧行列的遮挡,有时候这会挡住我们断点调试时打的断点. 如图所示: 这时候我们在 ...