热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JAVA之Lambda表达式

JAVA之Lambda表达式,Go语言社区,Golang程序员人脉社


Lambda表达式入门

Lambda表达式支持将代码块作为方法参数,Lambda表达式允许使用更简洁的代码块来创建只有一个抽象方法的接口(函数式接口)的实例。

Lambda表达式的代码块可以代替那些函数式接口的匿名内部类创建对象,Lambda表达式的代码块将会代替实现抽象方法的方法体,Lambda表达式就相当于一个匿名方法。

也就是说,Lambda表达式的主要作用就是代替匿名内部类的繁琐语法。

Lambda表达式由三部分构成


  1. 形参列表。形参列表可以省略形参类型。如果形参列表只有一个参数,那么可以省略形参列表的圆括号
  2. 箭头(->)
  3. 代码块。如果代码块只包含一条语句,Lambda表达式允许省略代码块的花括号,如果只有一条return语句,那么可以省略return关键字(当Lambda表达式需要返回值,而代码块中仅有一条省略了return的语句,那么表达式会自动返回这条语句的值)
下面举个例子:

interface ProcessArray
{
abstract void calculate(int[]a);
public static void end()
{
System.out.println("运算结束");
}
}
public class Test1 {
public void process(int []array,ProcessArray pa)
{
pa.calculate(array);
ProcessArray.end();

}
public static void main(String []args)
{
int []ia=new int[]{2,3,4,5,6,7};
Test1 test=new Test1();
test.process(ia, (a)->{
int sum=0;
for(int i=0;i sum+=ia[i];
System.out.println(sum);
});
}
}
运行结果如下:


Lambda表达式实际上会被当成一个“任意类型的对象”,到底需要当成何种类型的对象,这取决于运行环境的需要。



Lambda表达式与函数式接口
Lambda表达式的目标类型必须是“函数式接口”,也就是说,该接口中可以有多个默认方法、类方法,但只能有一个抽象方法。



同一个Lambda表达式的目标类型完全可能是变化的,但是Lambda表达式实现的匿名方法和目标类型(函数式接口)中位于的抽象方法有相同的形参列表



Lambda表达式的目标类型必须是明确的函数式接口,为了保证这一点,一般以下三种方式使用Lambda表达式




  • 将Lambda表达式的目标类型是一个明确的函数式接口
  • 将Lambda表达式赋值给函数式接口类型的参数传给某个方法
  • 使用函数式接口对Lambda表达式进行强制类型转换

对于第三种用法,举个例子:

public class Test2 {
public static void main(String[]args)
{
Object b=(Runnable)()->{
for(int i=0;i<100;i++)
{
System.out.println(i);
}
};
Thread t=new Thread((Runnable)b);
t.start();
}
}


经实测运行无误



方法引用和构造器引用

如果Lambda表达式的代码块只有一条代码,那么就可以在代码块中使用方法引用和构造器引用(P216)



引用类方法


以下方法引用代替Lambda表达式引用类方法



函数式接口中被实现方法的全部参数传该类方法作为参数



interface Converter
{
Integer conver(String from);
}
public class Test3 {
public static void main(String []args)
{
Converter c1=from->Integer.valueOf(from) ;
Converter c2=Integer::valueOf;
int x=c1.conver("99");
System.out.println(x);
int y=c2.conver("222");
System.out.println(y);
}
}


运行结果如下:






引用特定对象的实例方法

我简单改了一下上面的代码:

interface Converter
{
Integer conver(String from);
}
class Hello
{
public Integer sayHello(String from)
{
System.out.println("Hello "+from);
return 0;
}
}
public class Test3 {
public static void main(String []args)
{
Hello h=new Hello();
Converter c3=h::sayHello;
c3.conver("Black");
System.out.println(c3.conver("aaa"));
}
}


运行结果如下:




引用某类对象的实例方法


interface MyTest
{
String test(String a,int x,int y);
}
public class Test3 {
public static void main(String []args)
{
MyTest mt1=(a,b,c)->a.substring(b,c);
String str=mt1.test("Hello world", 3, 6);
System.out.println(str);
MyTest mt2=String::substring;
System.out.println(mt2.test("abcde", 2, 4));
}
}
输出结果如下:



引用构造器


interface SayHello
{
Hello test(String x);
}
class Hello
{
public Hello(String s)
{
System.out.println("创建Hello对象成功"+s);
}
public Integer sayHello(String from)
{
System.out.println("Hello "+from);
return 0;
}
}
public class Test3 {
public static void main(String []args)
{

SayHello sh1=s->new Hello(s);
System.out.println(sh1.test("white"));
SayHello sh2=Hello::new;
System.out.println(sh2.test("Black"));
}
}
运行结果如下:



Lambda表达式与匿名内部类的联系和区别


Lambda表达式是匿名内部类的一种简化,因此他可以部分取代匿名内部类的作用,它们有以下相同点:


  • 都可以直接访问“effectively final”的局部变量,以及外部类的成员变量(包括实例变量和类变量)
  • 创建的对象都可以直接调用从接口中继承的默认方法
和匿名内部类类似,当Lambda表达式访问局部变量,那么该局部变量等于有一隐式的final修饰,因此不可以对该局部变量重新赋值



匿名内部类实现的抽象方法的方法体允许条用接口中定义的默认方法,但Lambda表达式不可以。





PS:这应该是JAVA入门系列的最后一篇,下面我会开始数据结构系列和JAVA进阶系列




推荐阅读
  • Hadoop MapReduce 实战案例:手机流量使用统计分析
    本文通过一个具体的Hadoop MapReduce案例,详细介绍了如何利用MapReduce框架来统计和分析手机用户的流量使用情况,包括上行和下行流量的计算以及总流量的汇总。 ... [详细]
  • Java连接MySQL数据库的方法及测试示例
    本文详细介绍了如何安装MySQL数据库,并通过Java编程语言实现与MySQL数据库的连接,包括环境搭建、数据库创建以及简单的查询操作。 ... [详细]
  • Java中提取字符串的最后一部分
    本文介绍了如何使用Java中的substring()和split()方法来提取字符串的最后一部分,特别是在处理包含特殊字符的路径时的方法与技巧。 ... [详细]
  • 题目描述:Balala Power! 时间限制:4000/2000 MS (Java/Other) 内存限制:131072/131072 K (Java/Other)。题目背景及问题描述详见正文。 ... [详细]
  • 本文旨在探讨Swift中的Closure与Objective-C中的Block之间的区别与联系,通过定义、使用方式以及外部变量捕获等方面的比较,帮助开发者更好地理解这两种机制的特点及应用场景。 ... [详细]
  • 本文探讨了如何使用Scrapy框架构建高效的数据采集系统,以及如何通过异步处理技术提升数据存储的效率。同时,文章还介绍了针对不同网站采用的不同采集策略。 ... [详细]
  • 题目概述:Sereja 拥有一个由 n 个整数组成的数组 a1, a2, ..., an。他计划执行 m 项操作,这些操作包括更新数组中的特定元素、增加数组中所有元素的值,以及查询数组中的特定元素。 ... [详细]
  • C/C++ 应用程序的安装与卸载解决方案
    本文介绍了如何使用Inno Setup来创建C/C++应用程序的安装程序,包括自动检测并安装所需的运行库,确保应用能够顺利安装和卸载。 ... [详细]
  • 最近遇到了一个关于单链表的编程问题,这是来自福富公司的笔试题目。以往我通常使用C语言来解决这类问题,但这次决定尝试用Java来实现。该题目要求实现一个单链表,并完成特定的方法。 ... [详细]
  • 设计一个算法,用于计算给定字符串中出现的不同ASCII字符数量。该任务将重点考察字符串处理、集合操作以及基础的输入输出技术。 ... [详细]
  • Java多线程售票案例分析
    本文通过一个售票系统的实例,深入探讨了Java中的多线程技术及其在资源共享和并发控制中的应用。售票过程涉及查询、收款、找零和出票等多个步骤,其中对总票数的管理尤为关键。 ... [详细]
  • 本文详细介绍如何在SSM(Spring + Spring MVC + MyBatis)框架中实现分页功能。包括分页的基本概念、数据准备、前端分页栏的设计与实现、后端分页逻辑的编写以及最终的测试步骤。 ... [详细]
  • Go语言实现文件读取与终端输出
    本文介绍如何使用Go语言编写程序,通过命令行参数指定文件路径,读取文件内容并将其输出到控制台。代码示例中包含了错误处理和资源管理的最佳实践。 ... [详细]
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • 探讨 try-finally 结构中 finally 块的执行情况
    本文深入分析了 Java 中 try-finally 结构的执行机制,特别是探讨了在不同情况下 finally 块是否会得到执行。 ... [详细]
author-avatar
王聪明2011
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有