一.Lambda表达式的基础语法:

Java8中引入了一个新的操作符"->"该操作符称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆分为两部分:

左侧:Lambda表达式的参数列表

右侧:Lambda表达式所需要执行的功能,即Lambda体

语法一:无参数,无返回值

 () -> System.out.println("hello");

语法二:有一个参数,无返回值

 (x) -> System.out.println("hello" + x);

语法三:只有一个参数,无返回值

 x -> System.out.println("hello" + x);

语法四:有两个以上参数,又返回值,并且Lambda体中有多条语句

     Comparator<Interger> com = (x, y) -> {
System.out.println("hello");
return Interger.compare(x, y);
};

语法五:如果Lambda体只有一条语句,return和大括号都可以省略

 Comparator<Interger> com = (x, y) -> Interger.compare(x, y);

语法六:Lambda表达式参数列表的数据类型可以省略不写,JVM编译器通过上下文推断出数据类型(“类型推断”)

 Comparator<Interger> com = (Interger x,Interger y) -> Interger.compare(x, y);

二.使用Lambda优化程序

接口->外部实现类->静态内部类->局部内部类->匿名内部类->lambda->方法引用方式

 /**
* 定义一个函数式接口:
* 函数式接口是一个接口中只有一个非默认且非Object类的方法
*/
@FunctionalInterface
interface ILike {
//默认都为抽象方法(一般都省略abstract)
void lambda(); default void print() {
System.out.println("我是默认方法");
} String toString(); boolean equals(Object obj);
} //外部实现类
class Like1 implements ILike { @Override
public void lambda() {
System.out.println("外部实现类");
}
} public class TestLambda { public static void printLambda() {
System.out.println("我是TestLambda类的静态方法");
} //静态内部类
static class Like2 implements ILike { @Override
public void lambda() {
System.out.println("静态内部类");
}
} public static void main(String[] args) { ILike like = new Like1();
like.lambda(); like = new Like2();
like.lambda(); //局部内部类
class Like3 implements ILike { @Override
public void lambda() {
System.out.println("局部内部类");
}
} like = new Like3();
like.lambda(); //匿名内部类,没有类的名字,必须借助接口或者父类实现
like = new ILike() {
@Override
public void lambda() {
System.out.println("匿名内部类");
}
}; like.lambda(); //lambda表达式
like = () -> System.out.println("lambda表达式");
like.lambda(); //方法引用方式(类::静态方法)
like = TestLambda::printLambda;
like.lambda(); } }

三.Lambda表达式的延迟执行

目的:避免性能浪费

字符串是否需要拼接用例:

  • 普通方法:如果level不符合要求依旧会拼接字符串造成性能浪费
  • lambda表达式:level不符合要求不会拼接,减少性能浪费
  • 使用供给型接口优化lambda
 public class demo02Logger {

     public static void showLog1(int level, String message) {
if (level == 1) {
System.out.println("showLog1:level1:" + message);
}
} public static void showLog2(int level, MessageBuilder mb) {
if (level == 1) {
System.out.println("showLog2:level1:" + mb.builderMessage());
}
} public static void showLog3(int level, Supplier<String> stringSupplier) {
if (level == 1) {
System.out.println("showLog3:level1:" + stringSupplier.get());
}
} public static void main(String[] args) {
String msg1 = "msg1";
String msg2 = "msg2";
String msg3 = "msg3"; //普通方法:如果level不符合要求依旧会拼接字符串造成性能浪费
showLog1(2, msg1 + msg2 + msg3); //lambda表达式:level不符合要求不会拼接,减少性能浪费
showLog2(1, () -> {
System.out.println("showLog2:level为1才执行拼接");
return msg1 + msg2 + msg3;
}); showLog2(2, () -> {
System.out.println("showLog2:level为2不执行拼接");
return msg1 + msg2 + msg3;
}); //使用供给型函数式接口
showLog3(1,() -> {
System.out.println("showLog3:level为1才执行拼接");
return msg1 + msg2 + msg3;
}); showLog3(2,() -> {
System.out.println("showLog3:level为2不执行拼接");
return msg1 + msg2 + msg3;
});
}
} @FunctionalInterface
interface MessageBuilder {
String builderMessage();
}

结果:

使用lambda优化了性能

 showLog2:level为1才执行
showLog2:level1:msg1msg2msg3
showLog3:level为1才执行
showLog3:level1:msg1msg2msg3

四.Lambda表达式需要“函数式接口”的支持

函数式接口:接口中只有一个抽象的方法,称之为函数式接口。可以使用注解 @FunctionalInterface 修饰(用于检查是否是函数式接口)

Java8 内置的四大核心函数式接口:(还有很多子接口)

  • Consumer<T>:消费型接口

    • void accept(T t);
  • Supplier<T>:供给型接口
    • T get();
  • Function<T,R>:函数型接口(将T类型转换为R类型)

    • R apply(T t);
  • Predicate<T>:断言型接口
    • boolean test(T t)

1.方法引用:若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”(理解为Lambda的另一种表现形式)

主要有三种语法格式:(所引用的方法参数和返回值要与函数式接口的抽象方法参数和返回值一致)

  • 对象::实例方法
  • 类::静态方法
  • 类::实例方法(必须是第一个参数为实例方法,调用者第二个参数为实例方法的参数)
 @Test
public void test() { //lambda
PrintStream ps = System.out;
Consumer<String> con1 = (x) -> ps.println(x);
con1.accept("con1"); //对象::实例方法名(返回值和参数需要与方法调用者一致)
Consumer<String> con2 = System.out::println;
con2.accept("con2"); //lambda
Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y);
System.out.println(com1.compare(5, 6)); //类::静态方法名(返回值和参数需要与方法调用者一致)
Comparator<Integer> com2 = Integer::compare;
System.out.println(com2.compare(5, 6)); //lambda
BiPredicate<String, String> bp1 = (x, y) -> x.equals(y);
System.out.println(bp1.test("aaa","aaa")); //类::实例方法名(条件是第一个参数为实例方法调用者,第二个参数为实例方法的参数)
// (返回值和参数需要与方法调用者一致)
BiPredicate<String,String> bp2 = String::equals;
System.out.println(bp2.test("aaa","aaa")); }

2.构造器引用:

格式:ClassName::new(所调用的构造器参数要与函数式接口的抽象方法参数一致)

     class Mytest{

         private Integer id;
private String testmes; public Mytest() {
} public Mytest(Integer id) {
this.id = id;
} public Mytest(Integer id, String testmes) {
this.id = id;
this.testmes = testmes;
} @Override
public String toString() {
return "Mytest{" +
"id=" + id +
", testmes='" + testmes + '\'' +
'}';
}
} @Test
public void test2(){ //Lambda(调用无参构造函数)
Supplier<Mytest> sup1 = ()->new Mytest();
System.out.println(sup1.get()); //构造器引用方式(调用无参构造函数)
Supplier<Mytest> sup2 = Mytest::new;
System.out.println(sup2.get()); //Lambda(调用一个参数和一个返回值构造函数)
Function<Integer,Mytest> fun1 = (x)->new Mytest(x);
System.out.println(fun1.apply(3)); //构造器引用方式(调用一个参数和一个返回值构造函数)
Function<Integer,Mytest> fun2 = Mytest::new;
System.out.println(fun2.apply(3)); //Lambda(调用两个参数和一个返回值构造函数)
BiFunction<Integer,String,Mytest> bi1 = (x,y)->new Mytest(x,y);
System.out.println(bi1.apply(3,"mytest3")); //构造器引用方式(调用两个参数和一个返回值构造函数)
BiFunction<Integer,String,Mytest> bi2 = Mytest::new;
System.out.println(bi2.apply(3,"mytest3")); }

3.数组引用

格式:Type::new

     @Test
public void testarray(){ //lambda
Function<Integer,String[]> fun1 = (x) -> new String[x];
System.out.println(fun1.apply(10).length); //10 //数组引用
Function<Integer,String[]> fun2 = String[]::new;
System.out.println(fun2.apply(15).length); //15 }

Java中lambda表达式学习的更多相关文章

  1. Java中lambda表达式详解

    原文地址:http://blog.laofu.online/2018/04/20/java-lambda/ 为什么使用lambda 在java中我们很容易将一个变量赋值,比如int a =0;int ...

  2. Java 8 Lambda表达式学习和理解

    Java 8 Lambda表达式和理解 说明:部分资料来源于网络 时间:20190704 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性.Lambda 允许把函数作为一 ...

  3. java 8 中lambda表达式学习

    转自 http://blog.csdn.net/renfufei/article/details/24600507 http://www.jdon.com/idea/java/10-example-o ...

  4. Java中Lambda表达式的使用

    简介(译者注:虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能.本人建议不要乱用,因 ...

  5. Java中Lambda表达式的使用(转)

    https://www.cnblogs.com/franson-2016/p/5593080.html 简介(译者注:虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖" ...

  6. 快速掌握Java中Lambda表达式的用法

    Lambda表达式的作用: Lambda表达式的作用就是简化代码开发,让代码看起来更加简介.它是用来简化匿名内部类的.但是并不是所有的匿名内部类都能用Lambda表达式简化,Lambda表达式是有使用 ...

  7. Java中Lambda表达式的简单使用

    Lambda表达式是Java SE 8中一个重要的新特性.你可以把 Lambda表达式 理解为是一段可以传递的代码 (将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风格 ...

  8. Java中lambda(λ)表达式的语法

    举一个排序的例子,我们传入代码来检查一个字符串是否比另一个字符串短.这里要计算: first.length() - second.length() first和second是什么?他们都是字符串.Ja ...

  9. 为什么Java中lambda表达式不能改变外部变量的值,也不能定义自己的同名的本地变量呢?

    作者:blindpirate链接:https://www.zhihu.com/question/361639494/answer/948286842来源:知乎著作权归作者所有.商业转载请联系作者获得授 ...

随机推荐

  1. 部署elasticsearch(三节点)集群+filebeat+kibana

    用途 ▷ 通过各个beat实时收集日志.传输至elasticsearch集群 ▷ 通过kibana展示日志 实验架构 名称:IP地址:CPU:内存 kibana&cerebro:192.168 ...

  2. 推荐一个GOLANG入门很好的网址

    推荐一个GOLANG入门很好的网址,栗子很全 https://books.studygolang.com/gobyexample/

  3. 2019 创蓝253java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.创蓝253等公司offer,岗位是Java后端开发,因为发展原因最终选择去了创蓝253,入职一年时间了,也成为 ...

  4. POST请求转换为PUT或者Delete请求、处理post请求乱码的过滤器、Get请求乱码

    在web.xml中配置 <!--配置HiddenHttpMethodFilter : 将所有的POST请求转换为PUT或者Delete请求 --><filter> <fi ...

  5. Java自学-接口与继承 重写

    Java 重写方法 子类可以继承父类的对象方法 在继承后,重复提供该方法,就叫做方法的重写 又叫覆盖 Override 步骤 1 : 父类Item 父类Item有一个方法,叫做effect packa ...

  6. English--动词语态

    English|动词语态 动词的语态在理解长难句中很重要.了解被动语态与主动语态,掌握语态的变化方式. 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点的描述.力求不含任何的自我 ...

  7. 14、vue-cli脚手架搭建项目

    1:全局安装vue-cli:npm install --global vue-cli2:进入你的项目目录:cd myProject3:初始化创建项目:vue init webpack vue-demo ...

  8. java Elasticsearch 进行嵌套子聚合

    聚合子查询: TermsAggregationBuilder aggregation = AggregationBuilders.terms("dt_id").field(&quo ...

  9. Sql 语句中 IN 和 EXISTS 的区别

    IN 语句:只执行一次 确定给定的值是否与子查询或列表中的值相匹配.in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选.所以相对内表比较小的时候,in的速度较快 ...

  10. 【Netty】初识Netty

    一.为什么会出现Netty 之前我们使用通用的应用程序或库来相互通信.例如,我们经常使用HTTP客户机库从web服务器检索信息,并通过web服务调用远程过程调用.然而,通用协议或其实现有时伸缩性不是很 ...