当前位置: 首页 > 编程日记 > 正文

java 8 lambda reduce_JDK8新特性Lambda表达式体验

“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口。

Lambda简介

Lambda表达式的语法由参数列表、箭头符号->和函数体组成。函数体既可以是一个表达式,也可以是一个语句块。

比如:

(int x, int y) -> x + y;

具体的Lambda表达式的介绍可以看这篇博客,写得挺详细的。

Java Lambda表达式示例

下面就用一些例子来体验一下Lambda表达式。

遍历集合

比如我们现在要遍历一个List:

List list = Arrays.asList("Hello", "JDK8", "and", "Lambda");

JDK8之前的写法:

for (String s : list) {

System.out.println(s);

}

用Lambda表达式写法:

list.forEach(s -> System.out.println(s));

可以看到,无论是代码量和可读性都得到了提高。

在此基础上还可以再用隐式表达式进行简化:

list.forEach(System.out::println);

匿名类

在Java中很多时候我们要用到匿名类,比如线程Runnable、FileFilter和Comparator等等。

而匿名类型最大的问题就在于其冗余的语法。

这里用Comparator做例子。

比如我们有一个Cat类,表示猫,有名字、高度和重量这些属性。

package com.fengyuan.model;

import lombok.AllArgsConstructor;

import lombok.Data;

public @Data @AllArgsConstructor class Cat {

private String name;

private double height;

private double weight;

}

我们创建3只猫,存到List中:

List catList = new ArrayList<>();

// 请无视这些数据的合理性,我乱写的

catList.add(new Cat("cat1", 10.3, 3.6));

catList.add(new Cat("cat2", 9.3, 4.6));

catList.add(new Cat("cat3", 9.5, 4.0));

然后我们现在要对这个List进行排序,但是现在不知道是要怎么排,所以我们要定义一个比较器,指定用高度或者是重量来排序。

JDK8之前的写法:

// 指定用高度来排序

Collections.sort(catList, new Comparator() {

@Override

public int compare(Cat o1, Cat o2) {

if (o1.getHeight() > o2.getHeight()) {

return 1;

} else if (o1.getHeight() < o2.getHeight()) {

return -1;

} else {

return 0;

}

}

});

而用Lambda,可以这样写:

Collections.sort(catList, (o1, o2) -> {

if (o1.getHeight() > o2.getHeight()) {

return 1;

} else if (o1.getHeight() < o2.getHeight()) {

return -1;

} else {

return 0;

}

});

继续用方法引用,可以简写到极致:

// 指定用重量排序

catList.sort(Comparator.comparing(Cat::getWeight));

// 要逆向排列也很简单

catList.sort(Comparator.comparing(Cat::getWeight).reversed());

到最后这种写法,已经简写到极致,而且可读性非常高。

函数式接口

JDK8增加了一个新的包:java.util.function,它里面包含了常用的函数式接口,比如Predicate、Consumer,Function等等。

接下来就体验一下Predicate和Consumer的用法。

我们现在有一个订单类,有id,金额,运费这些属性。这个订单有一个折扣方法,我们希望能够根据营销活动,动态修改优惠方案。

Order类:

package com.fengyuan.model;

import java.util.function.Consumer;

import java.util.function.Predicate;

import lombok.AllArgsConstructor;

import lombok.Data;

public @Data @AllArgsConstructor class Order {

private long id;

private double payment;

private double freight;

// 优惠政策

public Order discount(Order order, Predicate predicate, Consumer consumer) {

// 满足Predicate的条件,返回true

if (predicate.test(order)) {

// 接收订单对象,对订单对象进行处理

consumer.accept(order);

}

return order;

}

}

其中

Predicate:接收T对象并返回boolean。

Consumer:接收T对象,没有返回值。

然后通过函数式编程,我们可以动态传入我们的优惠方案,比如99包邮:

// 新建一个订单,506.5的金额,10.0的运费

Order order = new Order(123, 506.5, 10.0);

// 满足金额>=99的条件,则设置运费为0

order.discount(order,

o -> o.getPayment() >= 99,

o -> o.setFreight(0));

这样一来,就能根据营销活动,修改我们的优惠方案。

除此之外,Predicate对象之间还能运用与或非这些逻辑操作,比如:

predicate1.and(predicate2);

predicate1.or(predicate2);

Stream

这里的Stream和I/O流不同,它更像具有Iterable的集合类。

Stream API引入的目的在于弥补Java函数式编程的缺陷,让java也支持map()、reduce()等函数式编程语言。

map

map(映射),将传入的函数依次作用到序列的每个元素。

比如说,有一个字符串列表,我们现在给列表里每个字符串调用toLowerCase()方法,转成小写字母。

List list = Arrays.asList("Hello", "JDK8", "and", "Lambda");

转成小写,用collect()把Stream再转回List,返回新的列表:

List newList = list.stream().map(s -> s.toLowerCase()).collect(Collectors.toList());

也可以返回一个字符串,指定连接符,我这里是用空格连接的:

String str = list.stream().map(s -> s.toLowerCase()).collect(Collectors.joining(" "));

也可以用隐式函数,String::toLowerCase来实现:

String str = list.stream().map(String::toLowerCase).collect(Collectors.joining(" "));

reduce

reduce(归约),将集合中所有值结合起来。

将一个整型List,先进行map:每个数都翻一倍,再进行reduce:所有数加起来,得到结果:

List numbers = Arrays.asList(10, 20, 30, 40, 50);

int result = numbers.stream().map(num -> num * 2).reduce((r, num) -> r += num).get();

变量捕捉

一个简单的例子,算出一个集合中最大值、最小值、平均值等等。

集合:

List numbers = Arrays.asList(4, 6, 65, 3, 44, 2, 17, 19);

计算:

int max = numbers.stream().mapToInt(x -> x).max().getAsInt();

int min = numbers.stream().mapToInt(x -> x).min().getAsInt();

long count = numbers.stream().mapToInt(x -> x).count();

double avg = numbers.stream().mapToInt(x -> x).average().getAsDouble();

int sum = numbers.stream().mapToInt(x -> x).sum();

也可以用IntSummaryStatistics类来得到统计结果:

IntSummaryStatistics stat = numbers.stream().mapToInt(x -> x).summaryStatistics();

int max = stat.getMax();

int min = stat.getMin();

long count = stat.getCount();

double avg = stat.getAverage();

long sum = stat.getSum();

结语

虽然平时项目的开发中还是比较少用到Lambda表达式,但是在以上这些体验中,确实是感受到了它的魅力。

相关文章:

php display_errors

// 检测开发环境public function setReporting(){if (APP_DEBUG true) {error_reporting(E_ALL);ini_set(display_errors,On);} else {error_reporting(E_ALL);ini_set(display_errors,Off);ini_set(log_errors, On);ini_set(error_log, RUNTIME_PATH. logs/error.log);}} 在p…

linux esd转iso,window_Win10 TH2正式版10586官方ESD映像怎么转换成ISO镜像?,今天phpstudy分享了Win10 TH2(Build - phpStudy...

Win10 TH2正式版10586官方ESD映像怎么转换成ISO镜像?今天phpstudy分享了Win10 TH2(Build 10586)各版本官方ESD映像下载地址&#xff0c;不过旧转换工具可能已不适用于新版ESD映像&#xff0c;特别是新版本增加了专业版和家庭版二合一映像&#xff0c;而以往都是单版本。本文使…

mysql在线上建索引,mysql 5.6在线DDL建索引测试

基本信息&#xff1a;mysql版本&#xff1a;(product)rootlocalhost [(none)]> select version;------------| version |------------| 5.6.29-log |------------1 row in set (0.00 sec)表payment的记录数:(product)rootlocalhost [sakila]> select count(*) from paym…

接口测试(postman jmeter)

接口&#xff1a;把client&#xff08;前端&#xff09;和server&#xff08;后端&#xff09;联系起来的就是接口&#xff0c;接口测试就是功能测试&#xff0c;进行接口测试首先得需要接口文档。 json是一种通用的数据格式&#xff0c;接口返回的数据都是json&#xff0c;jso…

c语言中delay找不到标识符,51单片机的c语言,请问哪里错了?延时没有效果,但是编译又不报错。delay应该怎么写,怎么引用啊?...

最佳答案西岸风2019-01-07 15:15i){LED00;LED21;LED40;delay(5000);}void main(void){while(1){for(i0;i<10;sbit LED0P1^0;sbit LED1P1^1;sbit LED4P1^4;sbit LED5P1^5;sbit LED2P1^2;sbit LED3P1^3;unsigned char i;sbit LED6P1^6;sbit LED7P1^7;void delay(unsigned int …

java 数据类型转换的一场_Java基础 — 四类八种基本数据类型

整型&#xff1a;整数类型int    一般的数据。long    极大的数据。short   用于特定的场合&#xff0c;比如底层的文件处理或者需要控制占用存储单元空间量的大数组。byte   用于特定的场合&#xff0c;比如底层的文件处理或者需要控制占用存储单元空间量的大数组。by…

vs 代理登入

https://msdn.microsoft.com/zh-cn/vstudio/dn771556.aspx转载于:https://www.cnblogs.com/CodingArt/p/6424180.html

php 为啥报错,php Soap 报错 求大神帮忙看看为什么

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼代码&#xff1a;$client new SoapClient("http://116.218.12.10:7012/businessService?wsdl", array(*trace* > true, *exceptions* > true));var_dump($client->__getFunctions());var_dump($client->__…

UWP: ListView 中与滚动有关的两个需求的实现

在 App 的开发过程中&#xff0c;ListView 控件是比较常用的控件之一。掌握它的用法&#xff0c;能帮助我们在一定程度上提高开发效率。本文将会介绍 ListView 的一种用法——获取并设置 ListView 的滚动位置&#xff0c;以及获取滚动位置处的项目。这里多说一句&#xff0c;由…

Deepin ROMS 安装详细流程

按照这个过程&#xff0c;完美安装&#xff0c;当然并不能排除会出现其他的问题。如果遇到了&#xff0c;那就老老实实上网搜吧。 转载于:https://www.cnblogs.com/haoorhuai/p/9502859.html

java struts2值栈ognl_Struts2 (三) — OGNL与值栈

一、OGNL表达式1.概述1.1什么是OGNL​ OGNL是Object-Graph Navigation Language的缩写&#xff0c;俗称对象图导航语言. 它是一种功能强大的表达式语言&#xff0c;通过它简单一致的表达式语法&#xff0c;可以存取对象的任意属性&#xff0c;调用对象的方法&#xff0c;遍历整…

c语言课程设计商品销售系统,c语言课程设计商品销售管理系统.pdf

C语言课程设计商品销售管理系统12020 年 4 月 19 日文档仅供参考商品销售管理系统目录一、 需求分析 2二、概要设计 2三、详细设计 4四、调试分析 14五、用户手册 14六、测试数据 15七、 附录 18— 1—22020 年 4 月 19 日文档仅供参考一、需求分析商品销售管理程序商品信息&am…

uploadhandler.php,WordPress Kernel Theme ‘upload-handler.php’任意文件上传漏洞

javascript中apply、call和bind的区别在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢.在说区别之前还是先总结一下三者的相似之处:1.都是用来改变函数的this对象的指向的.2.第一个参数都是this要指向的对 ...AIX UNIX 系统管理、维护与高可用集群建设—…

selenium--driver.switchTo()

在自动化测试中&#xff0c;会遇到多窗口、多iframe、多alert的情况。此时&#xff0c;会使用driver.switchTo()来解决。 下面时关于driver.switchTo()的详细介绍&#xff1a; 1.多windows操作。 在页面A上操作时&#xff0c;点击某个元素之后&#xff0c;可能会打开新的窗口。…

代理模式-积木模式

代理模式&#xff0d;积木模式 代理模式在实际开发中的确非常常见和常用&#xff0c;表面上代理模式是产生出一个代理类&#xff0c;作为访问实际实现类的代理&#xff0c;控制了外界对实际代理类的访问&#xff0c;在此基础上增加一些增强性的功能。实际上&#xff0c;还将实际…

java调用系统时间函数_JAVA自学笔记:不使用系统函数来计算日期处于当年的第多少天...

前段时间练习了一个求闰年的功能&#xff0c;现在就可以用上啦&#xff0c;这次写一个不借助类库的时间函数&#xff0c;利用基础代码写一个计算求日期处于当年的第多少天的函数。虽然也有简单的方法&#xff0c;例如直接定义每月的天数累加&#xff0c;然后加上当月的天数就可…

c语言输入学生成绩q退出,哭诉、拜求C语言学生成绩管理系统

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼/* Note:Your choice is C IDE */#include "stdio.h"#include "stdlib.h"#include "conio.h"#include "string.h"struct student{int num;char name[20];float score1;float score2;float…

php 所有魔术方法,PHP常用的魔术方法及规则

转&#xff1a;https://www.cnblogs.com/wanglijun/p/10926303.html1. __construct 具有构造函数的类会在每次创建新对象时先调用此方法;初始化工作执行。2. __desstruct 对象的所有引用都被删除或者当对象被显式销毁时执行。3.__call()在对象中调用一个不可访问方法时&#xf…

mysql启动后在哪里编程_启动mysql后怎么连接数据库

推荐答案一.mysql安装百度mysql下载一个即可。只是注意一下几个重要的数据&#xff1a;第一个就是Port Number :3306。端口号默认3306&#xff0c;一般不需要改&#xff0c;如果改了&#xff0c;请记住这个端口号。第二个就是password&#xff1a;本地数据库密码&#xff0c;默…

Python 出现 can't use a string pattern on a bytes-like object

# codingutf-8import urllib.requestimport reurl http://www.163.comfile d:/test.htmldata urllib.request.urlopen(url).read() r1 re.compile(<.*?>)c_t r1.findall(data)print(c_t)发现读取下来后,运行到第9 行,出现: cant use a string pattern on a bytes-l…

2018牛客网暑期ACM多校训练营(第十场)J(二分)

题目描述&#xff1a; 给你n个字符串&#xff0c;要让它们一个一个的合并成一个串。在合并的过程中&#xff0c;要保证被合并的串S是合并后的串r的前缀&#xff0c;模式串t是串r的子序。问你将这n个字符串合并后所得到的字典序最小的串是什么。 题目分析&#xff1a; 首先&…

实用c语言函数源码,C语言编写简单朗读小工具(有源码)

原标题&#xff1a;C语言编写简单朗读小工具(有源码)最近不少人在后台留言说学C都是面对枯燥的控制台程序&#xff0c;能不能体现一下C语言的实际用途&#xff0c;今天我们就理论结合实践一把&#xff1a;C语言结合VBS脚本编写一个简单的朗读小工具&#xff0c;做一个能够发音的…

php监听订单状态,ecshop数据库订单状态判断

order_info 表刚下完订单order_status 0shipping_status 0pay_status 0取消order_status 2shipping_status 0pay_status 0确认order_status 1shipping_status 0pay_status 0已付款order_status 1shipping_status 0pay_status 2配货中order_status 1shipping_status 3pay_status…

flask异步操作_Python Flask后端异步处理(三)

前一篇博文我们已经将基础知识和环境配置进行了介绍&#xff1a;首先编写一个celerytask.py文件进行Celery的配置&#xff0c;同时耗时任务也写在该文件中from celery import Celeryfrom init import appfrom SZheConsole import SZheScanapp.config[CELERY_BROKER_URL] redis…

Codeforces Round #308 (Div. 2) C. Vanya and Scales dfs

题目链接: http://codeforces.com/contest/552/problem/C 题意: 给你100个砝码&#xff0c;第i个砝码质量是w^i&#xff0c;然后问你能不能在有m的情况下&#xff0c;左边和右边都放砝码&#xff0c;使得这个天平平衡 题解: dfs直接暴力 对于这个砝码来说&#xff0c;只有3种选…

java中JVM的原理【转】

一、java虚拟机的生命周期&#xff1a; Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务&#xff1a;执行Java程序。程序开始执行时他才运行&#xff0c;程序结束时他就停止。你在同一台机器上运行三个程序&#xff0c;就会有三个运行中的Java虚拟机。 Java虚拟…

switch的case使用数组C语言,使用常量数组的元素作为switch语句中的case

我正在尝试将一组按键映射到一组命令.因为我处理来自多个地方的命令,所以我想在键和命令之间设置一个抽象层,这样如果我更改底层键映射,我就不必更改很多代码.我目前的尝试看起来像这样:// input.henum LOGICAL_KEYS {DO_SOMETHING_KEY,DO_SOMETHING_ELSE_KEY,...countof_LOGIC…

PHP上传文件函数move_upload,如何使用php中move_uploaded_file函数

我们平时上传的文件保存在临时文件夹中&#xff0c;例如/ tmp&#xff0c;但临时文件夹的内容在一段时间后会被删除&#xff0c;因此为了将来要使用上传文件&#xff0c;需要将内容保存在不太可能被任意删除的专用目录中&#xff0c;这时就需要使用move_uploaded_file函数&…

java的标记接口_Java中的标记接口?

我被教授&#xff0c;Java中的Marker接口是一个空接口&#xff0c;用于向编译器或JVM发送信号&#xff0c;实现此接口的类的对象必须以特殊方式处理&#xff0c;如序列化&#xff0c;克隆等。但最近我了解到&#xff0c;它实际上与编译器或JVM无关。例如&#xff0c;在Serializ…

Java Exception

先贴上一段Exception源码注释 1 /**2 * The class {code Exception} and its subclasses are a form of3 * {code Throwable} that indicates conditions that a reasonable4 * application might want to catch.5 *6 * <p>The class {code Exception} and any subc…