一、 lambada表达式简介

我们知道对于Java变量可以赋给其一个值,而如果想将"一块代码(一个完整的方法)"赋给一个Java变量,如下所示,怎么做呢?

可能认为就是下面的方式来实现

很显然,这个并不是一个很简洁的写法,我们采用Java8的Lambada表达式来实现,那么如何简化呢

整个过程:去掉修饰符(public等)、去掉函数的名字(因为已经赋给变量,变量知道此方法名--往后知道抽象方法唯一,不需要

方法名了)、去掉返回值类型(编译器可以推断)、去掉参数类型(编译器可以推断参数类型),最终的结果是下面的形式:

分析:这样的最终结果就是把"一块代码赋给一个变量"。或者说是"这个被赋给一个变量的函数"就是一个Lambada表达式,由于

Lambada可以直接赋给一个"变量",我们可以把Lambada(这里表示为变量)作为参数传递给函数

但是变量(Lambada表达式)的类型是什么呢?

说明:所有的Lambada的类型都是一个接口,而Lambada表达式本身("那段代码")就是一个接口的实现,这是理解Lambada的

一个关键所在,理解上可以这样认为:Lambada表达式就是产生一个实现接口中唯一的抽象方法的子实现类的对象,因此最终结

果:

函数式接口:接口中只有一个需要被实现的抽象函数

说明:为了避免后来的人在接口中增加新的接口函数,导致其有多个接口函数需要被实现,变成非函数式接口,引入了一个新的Annotation(注解):@FunctionalInterface。可以把他它放在一个接口前,表示这个接口是一个函数式接口,加上它的接口不会被编译,如果加上此标记就不能再添加其他的抽象方法,否则会报错。它有点像@Override,都是声明了一种使用意图,避免你把它用错。

总结:lambda表达式本质是匿名方法

二、 Lambda 表达式的结构

2.1 Lambada表达式的语法

Lambda 表达式在Java 语言中引入了一个新的语法元素和操作符。这个操作符为 “ ->”,该操作符被称为 Lambda 操作符或

箭头操作符。它将 Lambda 分为两个部分:

即:(参数列表)—>{express或statements}

左侧: 指定了 Lambda 表达式需要的方法参数列表←→右侧: 指定了 Lambda 体,即 Lambda 表达式要执行的功能

2.2 使用说明

(1)一个 Lambda 表达式可以有零个或多个参数,参数的类型既可以明确声明,也可以根据上下文来推断

(2)圆括号内,方法参数列表之间用逗号相隔

(3)当只有一个参数,且其类型可推导时,圆括号()可省略

(4)Lambda 表达式的主体可包含零条或多条语句,如果 Lambda 表达式的主体只有一条语句,花括号{}可省略,如果有返回值,return也可以省略,同时body中的“;”也可以省略。匿名函数的返回类型与该主体表达式一致

(5)如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

三、简单应用

(1)对比匿名内部类做为参数传递和Lambda表达式作为参数来传递--Runnable,Callable接口(具体看例子)

匿名内部类作为参数传递和Lamada表达式作为参数传递

例1:

package org.lamada;public class LamadaDemo0 {public static void main(String[] args) {//匿名内部类的形式开启一个线程new Thread(new Runnable() {@Overridepublic void run() {System.out.println("我爱你!");}}).start();//Lambada表达式创建匿名内部类开启一个线程new Thread(() -> System.out.println("-------------")).start();}
}

例2

package org.lamada;public class LamadaDemo1 {public static void main(String[] args) {//常见的函数式接口:Runnable、 Comparable--排序(是一个函数式接口吗?)Comparable<Integer> comparable=new Comparable<Integer>() {@Overridepublic int compareTo(Integer o) {return 0;}};//Lambada表达式的方法Comparable<Integer> com=(a)->a;int i = com.compareTo(3);System.out.println(i);}
}

例3

package org.lamada;import java.util.Comparator;
import java.util.TreeSet;public class LamadaDemo2 {public static void main(String[] args) {//TreeSet排序新高度---Comparator本身有泛型TreeSet<Integer> tereeSet = new TreeSet<>(new Comparator<Integer>() {@Overridepublic int compare(Integer a, Integer b) {return a + b;}});//Lambada表达式的形式new TreeSet<Integer>((a,b)->a-b);}
}

例4 自定义一个函数式接口

package org.lamada;@FunctionalInterface
public interface MyFunctionalInterface <T> {void method(T s);//自定义函数式接口---注意其定义//用一个注解 @FunctionalInterface 去检测这个接口是不是一个函数式接口
}

测试

package org.lamada;public class LamadaDemo3 {public static void main(String[] args) {//首先自定义一个函数式接口:MyFunctionalInterfacenew MyFunctionalInterface<String>() {@Overridepublic void method(String s) {}}.method("你好吗?");//Lamada表达式的用法MyFunctionalInterface<String> lamada=(s)-> System.out.println(s);}
}

(3)Lambda 需要函数式接口的支持,来看下我们Java1.7以前遇到的函数式接口:点击打开链接

在Java 8中有一个函数式接口的包,里面定义了大量可能用到的函数式接口(java.util.function)

(4)Java1.8中提供的一个新的一个接口函数包四大核心式接口

详见:点击打开链接,注意几个名词(消费型、供给型、函数型、断言型函数)

例5 使用function包中的函数式接口

package org.lamada;import java.util.function.Supplier;public class LamadaDemo4 {public static void main(String[] args) {new Supplier<Double>() {@Overridepublic Double get() {return 3.1;}};}
}

四、方法引用

概念:方法引用其实是Lambda表达式的另一种写法,当要传递给Lambda体的操作已经有实现的方法了,可以使用方法引用。

语法:使用操作符 “ ::” 将方法名和对象或类的名字分隔开来

几种常见形式:

(1)类名::静态方法
        (2)对象::实例方法

(3)类名::实例方法

注意:
 *  1. Lambda体调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保存一致

* 2.若Lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method;不管怎么说,实质还是抽象方法的实现

对比:相比而言省略参数列表,是因为二者的类型一致,主要凸显方法(重重之重!!)

应用:

package com.company;import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;public class LambdaDemo6 {public static void main(String[] args) {// 方法引用 :: 是Lambda表达式的另一种简写方式//类名::静态方法//对象::实例方法//类名::实例方法Supplier<Double> supplier = new Supplier<Double>() {@Overridepublic Double get() {return Math.random();}};Supplier<Double> supplier2=()->Math.random();//方法引用Supplier<Double> supplier3=Math::random;System.out.println("-------------------------------------");Consumer<String> consumer = new Consumer<String>() {@Overridepublic void accept(String s) {PrintStream out = System.out;out.println(s);}};PrintStream out = System.out;Consumer<String> consumer2=(s)->out.println(s);Consumer<String> consumer3=out::println;//方法引用也没有参数consumer3.accept("bbbb");System.out.println("------------------------------");Comparator<String> stringComparator = new Comparator<String>(){@Overridepublic int compare(String s1,  String s2) {//你对一个函数式接口中的抽象方法重写时,如果说你传的这两个参数//一个参数作为了调用者,一个参数作为了 传入者//那么你也可以使用方法引用来简写Lambda表达式return s1.compareTo(s2);}};Comparator<String> stringComparator2=(s1,s2)->s1.compareTo(s2);Comparator<String> stringComparator3=String::compareTo;System.out.println("------------------------------------------------");Comparator<Integer> comparator = new Comparator<Integer>() {@Overridepublic int compare(Integer a, Integer b) {return a.compareTo(b);}};Comparator<Integer> comparator2=(x,y)->x.compareTo(y);Comparator<Integer> comparator3=Integer::compareTo;}
}

六、构造器引用----创建对象的专属

概念和应用

概念:与函数式接口相结合,自动与函数式接口中方法兼容。可以把构造器引用赋值给定义的方法,与构造器参数列表要与接口

中抽象方法的参数列表一致!

细节问题:并没有说返回值类型,因此与返回值类型没有半毛钱关系,是对象创建简化的的福音

格式:ClassName:: new

注意:需要调用的构造器方法与函数式接口中抽象方法的参数列表保持一致

应用:自定义一个标记接口MyInterface,返回值类型为自定义类MyClass

MyInterface接口

package org.lamada;@FunctionalInterface
public interface MyInterface<T,R> {R method(T t);//有参---可以使用Java8中已经存在的Function---具备此特性
}

MyClass类

package org.lamada;public class MyClass {String s=null;public MyClass(String s) {//有参的构造方法--无参的更简单this.s=s;}
}

测试类

package org.lamada;public class LamadaDemo5 {public static void main(String[] args) {//(1)传统的方式MyInterface<String,MyClass> myInterface1 = new MyInterface<String,MyClass>() {@Overridepublic MyClass method(String s) {return new MyClass(s);}};//(2)Lamada方式---首先实现此方法MyInterface<String,MyClass> myInterface2=(s)-> new MyClass(s);//(3)构造器引用的方式---不管参数了列表了,简化方法体MyInterface<String,MyClass> myInterface3=MyClass::new;MyClass myclass = myInterface3.method("你好吗?");System.out.println(myclass.s);//不管哪种方法,调用时传实参的形式是一致的}
}

相关链接:点击打开链接,点击打开链接

JDK1.8之Lambada表达式一相关推荐

  1. lambada表达式总结

    前言 作为jdk1.8的新特性,8的标准库都开始大量使用lambda表达式了,你有什么理由不去学习lambda,这么简洁,这么爽的一种编程方法,不学不觉得可惜吗? lambda即λ,是匿名函数的意思, ...

  2. 第十节 Java工具包-Collections 流--lambada表达式

     collection为核心的接口,包含了多种不同类型的集合以及多种不同数据结构的实现的类 list  set queue都是在collection接口下的所以都有.add()方法 package c ...

  3. Lambada表达式的用法

    Lambada表达式是JDK1.8中最重要的新功能之一.使用Lambada表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类.代码看起来更简洁易懂.Lambada表达式同时还提升了对集合.框架的 ...

  4. 2.cocos2dx 3.2中语法的不同之处,lambada表达式的使用和function和bind函数的使用

    1        打开建好的T32  Cocos2dx-3.2的一个项目 2        设置Cocos显示窗口的位置是在AppDelegate.cpp中: 3  设置自适应窗口大小的代码是在上面的 ...

  5. lambada表达式

     lambda表达式 //C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作.Lambda的语法形式如下: //[函数对象参数](操作符重载函数参数)mutable或e ...

  6. Lambada表达式常用案例(技能题)

    一:Lambada表达式的结构 1)Lambada表达式的结构我们可以看成三部分 () -> {},箭头左边是参数,右边是执行体,箭头是格式 二:使用案例(List为主的操作) 1)实体对象 @ ...

  7. lambada表达式介绍

    前言 在其他语言中,函数式编程是很常见的,java8中为了支持函数式编程,新增了lambada表达式.lambada表达式其实是匿名内部类和闭包的一种符号表示,至于概念性的问题,大家不必深究,lamb ...

  8. Python(十)lambada表达式

    一.Lambda 表达式 概念:是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数. ...

  9. lambada表达式理解

    lambada表达式是替换匿名内部类的函数式接口实现类 函数式接口 只有一个抽象方法的接口(可以有默认方法和静态方法),通常带有@FunctionalInterface注解 常用函数式接口 Predi ...

最新文章

  1. UNPIVOT的详细说明
  2. 转载:(C/C++函数返回多个值)
  3. 王爽《汇编语言(第三版)》检测点11.1
  4. InnoDB 的辅助索引叶子节点为什么不直接保存的记录地址而要存主键键值
  5. C++工程通过opencv找到自己定义的矩形中的两平行线的距离
  6. vc red.msi matlab,vc_red.msi
  7. Alex 的 Hadoop 菜鸟教程: 第15课 Impala 安装使用教程
  8. 十六、 方差分析--使用Python进行双因素方差分析
  9. 谷歌 Chrome 浏览器怎样开启黑暗模式?
  10. 吴伯凡-认知方法论-我的休息
  11. Foxmail邮箱提示错误:ssl连接错误,errorCode:5解决方法
  12. 电脑如何控制点击android手机,安卓手机怎么控制电脑?红米手机远程控制操作电脑方法...
  13. ①变量、常量、数据类型解释 ②标识符命原则 ③sizeof使用原则 ④float型科学计数法 ⑤字符转换到ASCII表 ⑥\t 的使用意义【黑马程序员视频】
  14. 在阿里云CentOS 7.4下安装WSTMart开源商城系统
  15. 首都师范 博弈论 6 5 5无限次重复博弈中的策略选择
  16. SpringBoot设置默认主页
  17. MyBatis动态批量插入、更新Mysql数据库的通用实现方案
  18. MSXML应用总结 开发篇(下)
  19. 记录一下自己学习网络安全的过程
  20. 研发部门压力管理探讨

热门文章

  1. vscode如何运行python文件_vscode怎么运行.py文件_编程开发工具
  2. 深度学习: ground truth 解释
  3. error怎么开机 fan_电脑开机后显示CPU Fan Error错误提示怎么办?分享六种解决方法...
  4. 计算机截图方法,电脑简单又实用的截图方法推荐
  5. firebase-admin的Java集成到服务器
  6. 异常检测——5月(task1)
  7. 算法的时间与空间复杂度介绍
  8. Autofac的基本使用
  9. Java 7~14各个版本新特性详解
  10. 如何学习自动化测试?一文4从个方面带你入门自动化测试【建议收藏】