JDK1.8之Lambada表达式一

2023-05-16

一、 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() {
            @Override
            public 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>() {
             @Override
             public 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>() {
            @Override
            public 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) {

        //首先自定义一个函数式接口:MyFunctionalInterface
       new MyFunctionalInterface<String>() {
           @Override
           public 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>() {
            @Override
            public 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>() {
            @Override
            public Double get() {
                return Math.random();
            }
        };

        Supplier<Double> supplier2=()->Math.random();//方法引用

        Supplier<Double> supplier3=Math::random;

        System.out.println("-------------------------------------");
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public 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>(){

            @Override
            public 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>() {
            @Override
            public 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>() {
            @Override
            public 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);

        //不管哪种方法,调用时传实参的形式是一致的



    }
}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JDK1.8之Lambada表达式一 的相关文章

  • CentOs7.5yum安装JDK1.8详细过程

    先查看有哪些可安装的 yum list java root 64 VM 16 35 centos yum list java Loaded plugins fastestmirror langpacks Loading mirror spe
  • RedHat Linux下安装JDK1.7报错Permission denied

    在RedHat Linux5 中安装JDK1 7时 xff0c 当我解压jdk xff0c 并且配置好了环境变量 xff0c 测试的时候 xff0c 报以下错误 root 64 jingfeng01 java version Error d
  • Linux安装jdk1.8和配置环境变量

    每次感觉配这个都很简单 xff0c 但每次都要查一下 xff0c 毕竟配错一点 后面都比较麻烦 xff0c 记录一下 xff0c 方便以后查看 linux 下安装jdk和windows下的安装是一样的 xff0c 之前在windows安装的
  • MacBook安装jdk1.8方便快捷稳定的方法

    MacBook安装jdk方便快捷稳定的方法 最简单快捷的jdk1 8安装 先查看有没有安装jdk xff1a java version 这样就是没有安装 然后去官网下载 下载地址 xff1a https www java com zh CN
  • (linux)CentOS -yum 安装jdk1.8

    1 搜索jdk安装 xff1a yum search java grep jdk 2 安装jdk 1 8 xff1a yum install java 1 8 0 openjdk 查看是否安装成功 xff1a java version 3
  • JDK1.8之Lambada表达式一

    一 lambada表达式简介 我们知道对于Java变量可以赋给其一个值 而如果想将 34 一块代码 一个完整的方法 34 赋给一个Java变量 如下所示 xff0c 怎么做呢 xff1f 你可能认为 就是下面的方式来实现 很显然 xff0c
  • CentOS7安装Oracle JDK1.8

    JDK1 8下载地址 https www oracle com java technologies javase javase8 archive downloads html 需要登录之后才能下载文件 xff0c 下载jdk 8u202 l
  • Collections.sort和Arrays.sort在jdk1.6和jdk1.7中区别

    1 写这边文章的原因 xff1a 最近在线上产品环境发现了部分用户数据返回排序问题 xff08 和之前理想中的排序不太一样 xff09 xff0c 由于服务器是集群配置 xff0c 猜测肯定是某一台排序服务出了问题 xff08 之前工作中也
  • jdk1.8中HashMap的扩容,从新增第一个元素开始

    置灰部分在当前场景下不考虑 1 新增第一个元素 新增第一个元素总结 xff1a 先进行数组容量初始化 xff0c 初始大小为16 xff0c 扩容界限为12 xff0c 再找出数组对应位置 xff0c 将新增的值放入 2 继续新增元素 xf
  • (Linux)Debian下安装JDK1.8.0

    昨晚花了两个多小时查资料 xff0c 在Debian下安装了jdk和tomcat xff0c 记录一下 查看Linux版本 xff1a uname span class hljs operator a span 我的是64位的 在oracl
  • debian中安装jdk1.8

    jdk版本 xff1a jdk 8u211 linux x64 tar gz 一 jdk官方下载地址 xff1a https www oracle com technetwork java javase downloads jdk8 dow
  • 【JDK1.8 新特性】Lambda表达式

    1 什么是Lambda表达式 xff1f Lambda 是一个匿名函数 xff0c 我们可以把 Lambda 表达式理解为是一段可以传递的代码 xff08 将代码像数据一样进行传递 xff09 使用它可以写出更简洁 更灵活的代码 作为一种更
  • linux配置jdk1.8环境

    配置环境变量 vim span class token operator span etc span class token operator span profile 加入 根据自己jdk存放的路径 export JAVA HOME sp
  • HashMap在JDK1.7和1.8中的实现

    一 初窥HashMap HashMap是应用更广泛的哈希表实现 xff0c 而且大部分情况下 xff0c 都能在常数时间性能的情况下进行put和get操作 要掌握HashMap xff0c 主要从如下几点来把握 xff1a jdk1 7中底
  • AbstractQueuedSynchronizer源码阅读(1)(AQS JDK1.8)

    AbstractQueuedSynchronizer 前言AbstractQueuedSynchronizer xff08 1 xff09 JDK 1 8 用途主要源码分析Node内部类ConditionObject类重要方法 主要的属性及
  • ReentrantLock源码阅读(1)(JDK1.8)

    ReentrantLock 前言ReentrantLock JDK 1 8 实现了Lock接口Sync类NonfairSync类FairSync类重要属性和方法 总结 前言 最近在使用Java 并发包时遇到一些问题 xff0c 感觉对于其还
  • JDK1.8Stream根据条件过滤出两个List集合中不一样的数据

    文章目录 前言1 基础类2 核心代码2 1 单条件筛选2 2 多条件筛选 前言 需求 xff1a 对两个数据库 xff08 一个SqlServer xff0c 一个MySQL xff09 xff0c 同一张表做数据同步 xff0c 保证两边
  • linux jdk1.8 64位下载永久地址,ubuntu,centos,java

    https pan baidu com s 1A4cl3vUWCtiHxJ9eHK2ApQ 密码 j8dg 转载于 https www cnblogs com avit p 11167487 html
  • JDK1.8(jdk8.0)新特性

    Java is still not dead and people are starting to figure that out 本教程将用带注释的简单代码来描述新特性 xff0c 你将看不到大片吓人的文字 一 接口的默认方法 Java
  • centos安装jdk1.8

    Linux平台安装JDK的方式大致有三种 xff08 rpm yum 手动安装 xff0c 这里简单介绍手动安装JDK的方式 一 去Oracle官网下载所需JDK包 这里跟windows平台差不多 xff0c 去官网查找链接下载对应JDK安

随机推荐

  • 【Minecraft】【ModPC】【我的世界】 我的世界电脑版如何进入网络游戏?

    我的世界电脑版如何进入网络游戏 xff1f 须知 看看就好 xff0c 不要频繁使用modpc xff0c 破坏游戏玩家体验 xff01 不知道为什么Win11会用着用着就会闪退 降级到Win10就什么事也没有 下载 ModPC下载 包含普
  • WindwosServer系统一些设置【网卡驱动修复】【安装UWP应用】【服务器管理取消开机自启动】

    WindwosServer系统一些设置 这里以2022为例 xff1a 第一 网卡驱动丢失修复 此教程只针对I219 V LM网卡 xff01 小知识 xff1a 当电脑没网时 xff0c 将手机和电脑用USB数据线连接 打开设置 xff1
  • dp最长不上升子序列 二分upper lower+贪心

    题意 找出最长不上升子序列长度 再找出最长不下降子序列最大长度 写法运用了指针 减少了代码量 include lt iostream gt include lt algorithm gt using namespace std const
  • 小米平板5ProWIFI(elish)刷ArrowOS

    文章目录 警告下载奇兔刷机系统本体及Recovery 清除数据刷入AospRec开始刷入警告 完成设置输入法 变砖头了qwq又是警告 芝士截图Root方法结尾 警告 此文章只针对 小米平板5Pro Wifi版本 xff08 elish xf
  • 【宝塔】【Windows】【Blessing-Skin】【我的世界】用宝塔Windows搭建皮肤站

    文章目录 前言所需环境相关链接安装宝塔安装步骤访问宝塔同意协议 安装环境安装WNMP添加站点 开始安装皮肤站配置网站配置Nginx URL重写规则 xff08 即 伪静态 xff09 配置PHP 安装皮肤站 一些小调整安装插件常见问题 插件
  • ping的详细过程学习笔记

    pc1 ping pc2 也就是pc1 xff1a 192 168 1 1 ping pc2 xff1a 192 168 1 2 属于同一网段的ping过程 步骤1 ping开始 即后台运行192 168 1 1 ping 192 168
  • FTPClient上传文件内容为空/损坏/缺失

    项目场景 xff1a 项目场景 xff1a 本地项目联调OA系统的时候 xff0c 在发送审批时会传送相关附件 xff0c 该附件由本地项目上传至FTP xff0c OA系统会根据我们提供的路径和文件名去FTP中找到该文件 问题描述 xff
  • Debian9桌面设置

    本文由荒原之梦原创 xff0c 原文链接 xff1a http zhaokaifeng com p 61 665 新安装的Debian9桌面上啥都没有 xff0c 就像这样 xff1a 图 1 虽然很简洁 xff0c 但是用着不是很方便 x
  • 爬虫遇到Cloudflare问题

    网址 xff1a https opensea io rankings sortBy 61 seven day volume 返回代码 xff1a 403 遇到的问题 xff1a Access denied api opensea io us
  • java servlet写的网页猜数小游戏

    几年前 xff0c 用java servlet 写了个猜数的网页小游戏 xff1b 今天看了觉得有点意思 xff0c 贴出来怀旧一下 xff1a 1 代码如下 xff1a package cn wzb import java io impo
  • 安卓-system.img镜像文件过大问题

    3126 5 1SDK预置过多apk时导致编译otapackage时报错处理 xff1a 1 修改prebuilts python linux x86 2 7 5 lib python2 7 zipfile py文件中为ZIP64 LIMI
  • 使用Tesseract-OCR识别图片中的文字并生成双层PDF

    识别图片中的文字并不是很困难 如果自己训练一个文字识别的深度学习程序去识别也是可以 xff0c 但是太费劲 Tesseract OCR是一个开源的文字识别引擎 xff0c 并且支持包括中文在内的多国语言 只要将语言配置上去 xff0c 就可
  • iptables(三)iptables命令详解

    一 语法规则 iptables t table COMMAND chain CONDITION j ACTION t table 是指 39 操作的表 39 filter nat mangle或raw 39 默认使用filter 39 CO
  • 单调栈lllll

    单调栈 xff0c 就是一个栈 xff0c 不过栈内元素保证单调性 即 xff0c 栈内元素要么从小到大 xff0c 要么从大到小 而单调栈维护的就是一个数前 后第一个大于 小于他的数 例题 xff1a P5788 模板 单调栈 例题就是一
  • cmake(六)Cmake添加工程子目录

    重点 xff1a 39 cmake3 39 和 39 make 39 命令 39 输出 39 的 39 深刻解读 39 备注 xff1a 当前阶段暂时不使用 39 IDE 39 工具 先 39 熟悉各指令 39 一 ADD SUBDIREC
  • nginx(二十七)长连接和短连接

    一 长连接和短连接 概念 1 39 HTTP 39 的长连接和短连接 39 本质 39 上是 39 TCP 39 长连接和短连接 2 在 39 HTTP 1 0 39 中默认使用 39 短 39 连接 解读 xff1a 客户端和服务器 39
  • nginx(七十四)nginx与跨域细节探究

    一 nginx配置跨域 知识铺垫 强调 xff1a 跨域是 39 浏览器 39 行为 39 不是 39 服务器行为 43 43 43 43 43 43 43 43 43 43 43 43 43 43 34 跨域的两种解决手段 34 43 4
  • HTTP1.1(一)HTTP协议

    一 HTTP协议定义 RFC7230定义 说明 xff1a 关注 39 红色关键字 39 无状态 解读 xff1a 连续的 39 两个 39 请求 后续的请求 39 不能依赖 39 前一个请求 各个请求是 39 相互独立 39 基于请求 相
  • nginx(七十五)nginx与Vary响应头细节探讨

    一 Vary nginx与Vary有关联的地方 nginx源码分析处理Vary响应头的逻辑 CORS和缓存 gzip vary 1 gzip vary on 如果设置为 39 开启 39 2 服务器 39 返回数据 39 时会在头部带上 3
  • JDK1.8之Lambada表达式一

    一 lambada表达式简介 我们知道对于Java变量可以赋给其一个值 而如果想将 34 一块代码 一个完整的方法 34 赋给一个Java变量 如下所示 xff0c 怎么做呢 xff1f 你可能认为 就是下面的方式来实现 很显然 xff0c