广告
返回顶部
首页 > 资讯 > 后端开发 > Python >详细解读Java的Lambda表达式
  • 821
分享到

详细解读Java的Lambda表达式

Java Lambda表达式Lambda表达式 2023-05-14 20:05:59 821人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录Lambda 表达式Lambada 简介简单的示例Lambda 表达式的组成部分函数式接口介绍几个 Java 中重要的函数接口Lambda 表达式 最早接触到 Lambda 表达

Lambda 表达式

最早接触到 Lambda 表达式的时候,是在学习 python 的时候,当时就很好奇。后来,才发现 Java 也有这个方面的知识,最近看了相关的知识,特定来总结一下。

Lambada 简介

lambda 表达式 是Java 8新加入的新特性,它在Java中是引入了函数式编程这一概念。那么什么是函数式编程呢?

函数式编程:函数式编程是面向数学的抽象,将计算描述为一种表达式求值。

我们平常所说的面向对象编程属于命令式编程,函数式编程和命令式编程的区别是:

  • 函数式编程关心数据的映射,命令式编程关系解决问题的步骤。
  • 函数式编程关系类型(代数结构)之间的关系,命令式编程关系解决问题的步骤。

函数式编程的本质:

函数式编程中的函数指的不是计算机中的函数,而是数学中的函数,即自变量的映射。即:一个函数的值仅取决于函数参数的值,不依赖其他状态。

严格意义上的函数式编程意味着不使用可变的变量,赋值,循环和其他命令式控制结构进行编程。

函数式编程的好处:

函数式编程的好处是主要是不可变性带来的。没有可变的状态,函数就是引用透明(Referential transparency)的和没有副作用的(No Side Effect)。

上面这些都是一些基本的概念,但是我们平时可能接触这些方面的东西比较少,所以一开始感觉函数式编程是很难得东西。

简单的示例

Talk is cheap, show me the code!

先来一个最简单的例子,可能也是介绍的最多的例子了。哈哈!

给按钮添加监视器。

使用匿名内部类的方式,进行添加。

submit.addActionListener(new ActionListener() {
	@Override
	public void actionPerfORMed(ActionEvent e) {
		JOptionPane.showMessageDialog(null, "点击了确定按钮", "确定", JOptionPane.INFORMATION_MESSAGE);
	}
});

这种方式的缺点:使用了很多的模板代码,真正必要的代码,只是方法体内的代码。所以,Java 8 引入的 Lambda 表达式可以简化这种代码(当然了,也是有限制的,不是所有的匿名内部类都可以,这个后面会提到。)。

使用 Lambda 表达式 简化代码

submit.addActionListener((e)->{
		JOptionPane.showMessageDialog(null, "点击了确定按钮", "确定", JOptionPane.INFORMATION_MESSAGE);
});

Lambda 表达式是一个匿名方法,将行为像数据一样进行传递。

说明

可以看出来,使用 Lambda 表达式简化后的代码表达变得更加清晰了,并且不用再去写繁琐的模板代码了。

进一步简化

参数括号和代码体的花括号也可以省略(只有一个参数时,可以省略圆括号,只有一行代码时,可以省略花括号)。

ActionListener listener = e->JOptionPane.showMessageDialog(null, "点击了确定按钮", "确定", JOptionPane.INFORMATION_MESSAGE);

小结
当使用 Lambda 表达式代替匿名内部类创建对象时,Lambda 表达式的代码块将会替代实现抽象方法的方法体,Lambda 就相当于一个匿名方法。

Lambda 表达式的组成部分

lambda 表达式由三部分组成:

  • 形参列表。形参列表允许省略形参类型。如果形参列表中只有一个参数,可以省略形参列表的圆括号。
  • 箭头(->)。英文短线和大于号。
  • 代码块。如果代码块只有一句,可以省略花括号。如果只有一条 return 语句,可以省略 return,lambda表达式会自动返回这条语句的值。

注:
之所以可以省略形参列表是因为 编译器 可以进行类型推断,例如:

List<Dog> dogs1 = new ArrayList<Dog>();

List<Dog> dogs2 = new ArrayList<>(); 

上面使用 菱形语法,可以省略尖括号里面的东西,这就是类型推断的作用
但是类型推断也不是万能的,不是所有的都可以推断出来的,所以有时候,还是要显示的添加形参类型,例如:

先不要管这个代码的具体作用。

BinaryOperator b = (x, y)->x*y;
//上面这句代码无法通过编译,下面是报错信息:无法将 * 运算符作用于 java.lang.Object 类型。
The operator * is undefined for the argument type(s) java.lang.Object, java.lang.Object
//添加参数类型,正确的代码。
BinaryOperator<Integer> b = (x, y)->x*y;

所以,类型推断不是万能的,如果编译器无法推断,那就是我们的错误,不要过度依赖编译器。有时候,显示的添加参数类型,还是很必要的,当然了,这需要去多练习。

函数式接口

前面了解了,Lambda 表达式可以代替匿名内部类,进而达到简化代码,表达清晰的目的。那么使用 Lambda 表示式的前提是什么呢?-- 函数式接口

Lambda 表达式的类型,也被称为 目标类型 (Target Type),它必须是一个函数式接口(Functional Interface)。所谓函数式接口,指的就是:只包含一个抽象方法的接口。(可以包含多个默认方法,静态方法,但必须只有一个抽象方法)。
注:Java 8 专门提供了一个注解:@FunctionalInterface。用于标注某个接口是函数式接口,这样编译时就会检查,如果该接口含有多个抽象方法,编译器就会报错。

上面使用 Lambda 表达式来为按钮添加了监视器,可以看出来,Lambda 表达式 代替了 new ActionListener()对象。

所以 Lambda 的表达式就是被当成一个对象。

例如:

ActionListener listener = e->JOptionPane.showMessageDialog(null, "点击了确定按钮", "确定", JOptionPane.INFORMATION_MESSAGE);

从上面这个例子中可以看出来,Lambda 表达式实现的是匿名方法–因此它只能实现特定函数式接口中的唯一方法。
所以 Lambda 表达式有下面两种限制:

Lambda 表达式的目标类型必须是明确的函数式接口。 Lambda 表达式只能为函数式接口创建对象。Lambda只能实现一个方法,因此它只能为含有一个抽象方法的接口(函数式接口)创建对象。

介绍几个 Java 中重要的函数接口

在这里插入图片描述

从这种表可以看出来,抽象方法的名字反而不是最重要的了,重要的是参数和返回值。 因为在写 Lambda 表达式的时候,也不要使用 抽象方法名了。

上面使用几个简单的例子来说明上面接口的应用:

测试代码

import java.text.ParseException;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;

public class Test {
	public static void main(String[] args) throws ParseException {
		//Lambda 表达式中的构造器引用,用于简化代码。
		Creat<Dog> c = Dog::new;
		Dog dog = c.creat("小黑", 15);
		System.out.println(dog.toString());
		
		Predicate<String> predicate = (Words)->{
			return words.length() > 20;
		};
		assert predicate.test("I love you yesterday and today!") : "长度小于20";
		assert !predicate.test("God bless you!") : "长度小于20";
		System.out.println("------------------------");
		
		Consumer<Dog> consumer = System.out::println;
		consumer.accept(dog);
		System.out.println("------------------------");

		Function<Dog, String> function = (dogObj)->{
			return dogObj.getName();
		};
		System.out.println(function.apply(dog));
		System.out.println("------------------------");
		
		Supplier<Dog> supplier = ()->{
			return new Dog("大黄", 4);
		};
		System.out.println(supplier.get());
		
		//一元操作符
		UnaryOperator<Boolean> unaryOperation = (flag)->{
			return !flag;
		};
		System.out.println(unaryOperation.apply(true));
		
		BinaryOperator<Integer> binaryOperator = (x, y)->x*y;
		int result = binaryOperator.apply(999, 9999);
		System.out.println(result);
	}
}

测试使用的实体类

public class Dog {
	private String name;
	private int age;
	
	public Dog(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Dog [name=" + name + ", age=" + age + "]";
	}
}

自定义函数式接口

@FunctionalInterface
public interface Creat<T> {
	public T creat(String name, int age);
}

运行截图就不放了,感兴趣的可以试一下。

说明
我这里直接使用 Lambda 创建了对象,然后调用了这个对象的方法(就是lambda 的代码块部分),真正使用的时候,都是直接传递 Lambda 表达式的,这种方法并不推荐,但是可以让我们很好的理解为什么? 可以看出来,Lambda 表达式的作用,最后还是需要调用 重写的抽象方法的,只不过使用表达更加清晰,简化了代码。

例如:

		List<Dog> dogs = new ArrayList<>();
		dogs.add(new Dog("大黄", 2));
		dogs.add(new Dog("小黑", 3));
		dogs.add(new Dog("小哈",1));
		//将行为像数据一样传递,使用集合的 forEach 方法来遍历集合,
		//参数可以是一个 Lambda 表达式。
		Consumer<? super Dog> con = (e)->{
			System.out.println(e);
		};
		dogs.forEach(con);
		System.out.println("--------------------------\n");
	
		//直接传递 Lambda 表达式,更加简洁
		dogs.forEach(e->System.out.println(e));
		System.out.println("--------------------------\n");

		//使用方法引用,进一步简化(可以看我的另一篇关于方法引用的博客)
		dogs.forEach(System.out::println);
		System.out.println("--------------------------\n");

		//使用 Lambda 对集合进行定制排序,按照年龄排序(从小到大)。
		dogs.sort((e1, e2)->e1.getAge()-e2.getAge());
		dogs.forEach(System.out::println);

可以看出来,通过使用 Lambda 表达式可以,极大的简化代码,更加方便的操作集合。值得一提的是:Lambda 表达式 和 Stream 的结合,可以拥有更加丰富的操作,这也是下一步学习的方向。

运行截图:

在这里插入图片描述

最后说一下

这个博客介绍了一些 Lambda 表达式的基本知识,但是描述的还是不是很清楚,哈哈!但是,希望通过这个简单的博客,可以帮助了解一些关于 Lambda 表达式的基本知识,这些都是很简单的东西,太难的部分,我可能暂时还没有触及到。

Lambda 表达式是一个匿名方法,将行为像数据一样进行传递。
这句话很关键,这是对 Lambda 的一个很好的总结。

到此这篇关于详细解读Java的Lambda表达式的文章就介绍到这了,更多相关Java Lambda表达式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详细解读Java的Lambda表达式

本文链接: https://www.lsjlt.com/news/204610.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详细解读Java的Lambda表达式
    目录Lambda 表达式Lambada 简介简单的示例Lambda 表达式的组成部分函数式接口介绍几个 Java 中重要的函数接口Lambda 表达式 最早接触到 Lambda 表达...
    99+
    2023-05-14
    Java Lambda表达式 Lambda表达式
  • Java中Lambda表达式使用详细解读
    目录前言一、Lambda表达式的简介二、Lambda表达式对接口的要求1.函数式接口2.@FunctionalInterface3.Lambda表达式的语法1.Lambda表达式的基...
    99+
    2023-05-18
    java  Lambda表达式使用 java  Lambda表达式 Lambda表达式使用
  • java lambda表达式详解
    一、Lambda初识 我们知道,在Java中,接口是不能实例化的,但是接口对象可以指向它的实现类对象。如果接口连实现对象都没有呢?那还可以使用匿名类的方式,如下: public class JavaTest { public ...
    99+
    2023-09-15
    java servlet jvm
  • Java 8的Lambda表达式详解
    本篇内容介绍了“Java 8的Lambda表达式详解”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!功能接口只包含一个方法的接口被称为功能接口...
    99+
    2023-06-17
  • Lambda表达式详解
    Lambda表达式 1. 为什么使用lambda表达式2. 入门案例3. lambda表达式组成4. lambda表达式使用4.1 语法格式一4.2 语法格式二4.3 语法格式三4.4 语法格...
    99+
    2023-09-01
    java jvm 算法
  • Java中Lambda表达式的使用详细教程
    目录简介格式实例函数式接口lambda作为参数遍历集合创建线程排序简介 说明 本文用示例展示Lambda表达式的用法。同时也会介绍Lambda的相关知识。 Lambda表达式介绍 L...
    99+
    2022-11-13
  • 关于java中的Lambda表达式的详细介绍
    什么是lambda表达式?lambda表达式是一个可传递的代码块,可以在后面执行一次或多次。推荐java相关视频教程:java学习视频例如:class action implements ActionListener{ @Override...
    99+
    2016-04-10
    java入门 java lambda表达式
  • Java中Lambda表达式的使用详解
    目录理解函数式接口以及 Lambda表达式的发展过程Lambda表达式及语法一起来看看具体的使用你需要注意什么Lambda的实际运用1.对集合排序2.遍历集合3.遍历集合(带条件)4...
    99+
    2022-11-12
  • C++Lambda表达式详解
    目录概述语法分析捕获列表关键字声明示例捕获列表按值传递总结概述 C++ 11 中的 Lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。Lambda 的语法形式如下: ...
    99+
    2022-11-12
  • python3 lambda表达式详解
    技术背景 lambda表达式本身是一个非常基础的python函数语法,其基本功能跟使用def所定义的python函数是一样的,只是lambda表达式基本在一行以内就完整的表达了整个函数的运算逻辑。这里我们简单展示一些...
    99+
    2022-06-02
    python的lambda函数 python中lambda的用法 python lambda函数怎么用
  • Java中Lambda表达式使用及详解
    Java中Lambda表达式使用及详解 前言 一、Lambda表达式的简介 Lambda表达式(闭包):java8的新特性,lambda运行将函数作为一个方法的参数,也就是函数作为参数传递到方法中。使用lambda表达式可以让代码更加...
    99+
    2023-08-16
    java
  • C++详细分析lambda表达式的本质
    例: stable_sort(words.begin(), words.end(), [](const string& s1, const string& s2...
    99+
    2022-11-13
  • 详解Java函数式编程和lambda表达式
    目录为什么要使用函数式编程JDK8接口新特性函数接口方法引用类型推断变量引用级联表达式和柯里化为什么要使用函数式编程 函数式编程更多时候是一种编程的思维方式,是种方法论。函数式与命令...
    99+
    2022-11-12
  • Java学习之Lambda表达式的使用详解
    目录Lamda表达式函数式接口Lambda表达式的推导函数式接口的不同类型Lambda表达式与函数式接口的简单应用Lambda表达式的优缺点Lamda表达式 λ希腊字母...
    99+
    2022-12-26
    Java Lambda表达式用法 Java Lambda表达式 Java Lambda
  • Java中Lambda表达式的进化之路详解
    目录Lambda表达式的进化之路为什么要使用Lambda表达式Lambda表达式的注意点下面是Lambda表达式的实现过程1.最开始使用的是定义外部实现类来完成接口2.开始使用静态内...
    99+
    2022-11-12
  • C#3.0中Lambda表达式详解
    在C#2.0中,微软给我们带来了一些新的特性,例如泛型,匿名委托等。然而,这些新的特性多多少少会给人一种从别的语言中“抄”来的感觉(例如泛型类似C++的模板,一些特性类似Java中的...
    99+
    2022-11-15
    C# Lambda
  • Java详细分析Lambda表达式与Stream流的使用方法
    目录LambdaStream流 Lambda        Lambda 表达式是一个匿名函数,我们可以把 lambda 表达式理解...
    99+
    2022-11-13
  • Java Lambda 表达式源码解析
    Java Lambda 源码分析 问题: Lambda 表达式是什么?JVM 内部究竟是如何实现 Lambda 表达式的?为什么要这样实现? 一、基本概念 1、Lambda 表达式 下面的例子中,() -> System.out.p...
    99+
    2021-12-25
    Java Lambda 表达式 Java Lambda源码
  • python中的lambda表达式用法详解
    本文实例讲述了python中的lambda表达式用法。分享给大家供大家参考,具体如下: 这里来为大家介绍一下lambda函数。 lambda 函数是一种快速定义单行的最小函数,是从 Lisp 借用来的,可以...
    99+
    2022-06-04
    表达式 详解 python
  • Java8新特性-Lambda表达式详解
    目录一、简介 特征引入Lambda表达式的总结三、Lambda表达式的使用无参、无返回值有参无返回值无参数有返回值有参数有返回值四、Lambda表达式的注意事项 ...
    99+
    2023-05-16
    java8新特性 lambda表达式 java8 lambda表达式
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作