在说一下Lambda表达式之前,我们先了解下为什么java要引入Lambda表达式
在java8 之前要将行为参数化我们有两种选择:
1.策略模式,根据参数传入的具体实现决定方法的实现
2.匿名内部类。
1的缺点是要新增新的行为必须创建新的行为并实现接口;2的缺点是不得不写很多模板代码,可读性差。
引入Lambda 前提条件
在很多函数式编程语言中允许将函数作为值,Java8也新增了这一特性,即允许方法作为值来传递,实现行为参数化。
在Java8之前筛选出隐藏文件可能需要这么做:
File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
public boolean accept(File file) {
return file.isHidden();
}
Java8之后只需要这么做:
File[] hiddenFiles = new File(".").listFiles(File::isHidden);
其中File::isHidden被称为方法应用,只要在方法体中存在执行体,方法应用就可以传递代码。
Lambda——匿名函数
函数式编程的概念:编写把函数作为值来传递的程序。
add方法对两个int值进行求和写作: (int x,int y) -> x+y,这部分可替代写个工具类然后调用如: Math::add,这样写更为简介,也不需要编辑新的类。
Lambda特性:
1.匿名:lambda表达式是没有名字的
2.函数:为什么叫函数而不是方法呢,因为Lambda函数不像方法那样属于某个类。但和方法一样Lambda有参数列表、函数主体返回类型、抛出异常。
3.传递:可作为值在方法参数中传递】
4.简洁
Lambda语法:
(parameters) -> expression或 (parameters) -> { statements; }
从左往右 lambda表达式有 参数列表、箭头、和函数主体构成。
函数体中使用了花括号需要显式使用return 返回,不使用花括号则不需要return关键字
函数式接口:
既然函数可作为值来传递那么肯定需要相应的规则,类似与我们把方法参数限定为指定接口类型一样,需要传递实现接口的类或者匿名内部类作为值,同样这里也按照规范定义了函数式接口,用来限定传递代码的参数和返回值(注意:Java8并没有引入函数这一类型)。
函数式接口与之前的接口区别就是只允许定义一个抽象方法(见下面),原因就不用多说了,都可以理解,函数式接口中方法的签名被叫做Lambda表达式的签名,编译器会根据函数式接口的签名和上下文进行类型推断保证不会出现编译错误,下面的是有效的。
Runnable a = () -> System.out.println(111);
a.run();
在Java8中类似Runnable、Comparable都是函数式接口。
@FunctionalInterface 注解
1、该注解只能标记在"有且仅有一个抽象方法"的接口上。
2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。
3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
4、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响,类似@override。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
使用函数式接口,java.util.function包
为了简化Java内置了常见的几种函数式接口Predicate<T>、Consumer<T>和Function<T,R>
Predicate有一个抽象方法test,输入为人意类型返回 boolean类型
Consumer有一个抽象方法accept,返回为空,输入为任意类型。
Function 有一个抽象方法返回为R类型输入为T类型。
方法引用
在大多数情况下我们应该考虑复用已有的东西而不是重新造轮子,方法引用就是Lambda表达式的一个
快捷方式,即方法应用会根据已有的方法实现来创建一个Lambda表达式。当你需要使用方法引用时,目标引用放在分隔符::前,方法的名称放在后面。例如, Apple::getWeight就是引用了Apple类中定义的方法getWeight。
方法引用主要有三类。
(1) 指向静态方法的方法引用(例如Integer的parseInt方法,写作Integer::parseInt)。
(2) 指向任意类型实例方法的方法引用(例如String的length方法,写作 String::length)。
(3) 指向现有对象的实例方法的方法引用(假设你有一个局部变量expensiveTransaction 用于存放Transaction类型的对象,它支持实例方法getValue,那么你就可以写expensive- Transaction::getValue)。
例如:
List<String> str = Arrays.asList("a","b","A","B");
str.sort((s1, s2) -> s1.compareToIgnoreCase(s2));
List<String> str = Arrays.asList("a","b","A","B");
str.sort(String::compareToIgnoreCase);
下面的写法是等效的:
Function<String, Integer> stringToInteger = (String s) -> Integer.parseInt(s);
Function<String, Integer> stringToInteger = Integer::parseInt;
还有一种特殊的函数应用:构造函数应用
分享到:
相关推荐
进度条.Lambda表达式.匿名方法.委托.类.集合.初始化.容易懂
Python 079.lambda表达式和匿名函数.mp4
2_Lambda表达式.zip2_Lambda表达式.zip2_Lambda表达式.zip
尾置返回类型特性和普通函数不样的是,lambda 表达式可以省略返回类型,由编译器推断,并且不需要使 decltype由编译器推断,返回类型为 bool若 la
通过多个示例详细演示了.Net中C#语言lambda表达式的基本用法,主要包括三个方面内容: 1.什么是lambda表达式 2.理解lambda表达式 3.使用lambda表达式
Stream、Lambda表达式练习.doc
Java8发布到现在至少3年了,但是对Lambda表达式不熟悉、看不懂、不会用的现象非常常见。 即使是升级到JDK1.8了,但是很多开发者依然是停留在1.8之前的开发方式,使用的也是非常老旧和过时的API,遇到函数式接口也是...
主要内容: ● 为何需要lambda,...第2章 Java lambda表达式的基础知识 23 第3章 流与管道介绍 55 第4章 终止流:收集与汇聚 91 第5章 起始流:源与分割迭代器 135 第6章 流的性能 167 第7章 使用默认方法演化API 195
适用人群 本源码资源适用于具备一定Java编程基础的开发人员和学习者。...2、函数式接口与Lambda表达式:学习如何使用Lambda表达式与不同类型的函数式接口进行交互,并了解如何通过Lambda表达式实现函数的传递和组合
主要介绍了解决mybatis-plus3.1.1版本使用lambda表达式查询报错的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
初学者lambda表达式学习demo
什么是Linq表达式什么是Lambda表达式.pdf 什么是Linq表达式什么是Lambda表达式.pdf
Lambda表达式与LINQ.rar Lambda表达式与LINQ.rar Lambda表达式与LINQ.rar
Lambda表达式之集合操作,代码里主要针对java 集合list的操作
Microsoft Visual Studio.Net(VS2010)编写的lambda表达式语法控制台程序。
Lambda表达式与LINQ.pdf Lambda表达式与LINQ.pdf Lambda表达式与LINQ.pdf
java lambda表达式,lambda 表达式基本上表达了函数式接口的实例(具有单一抽象方法的接口称为函数式接口。一个例子是 java.lang.Runnable)。lambda 表达式实现了唯一的抽象函数,因此实现了函数式接口 lambda ...
java8lambda表达式的安卓Studio工程Demo,供初步学习使用
Java8的lambda表达式