101.【用了Optional,同事都表示看不懂!】(二)

简介: 101.【用了Optional,同事都表示看不懂!】

3.线程匿名内部类实现

通常,我们也习惯用匿名内部类的方式创建并启动线程

通过下面示例会发现:Thread是个普通类,可以用匿名内部类,Runnable是个接口他也可以使用匿名内部类创建。

@Test
    public void test3(){
        new Thread(){  //线程实现匿名内部类, new Thread(){Ctrl+H}
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"创建线程1");
            }
        }.start(); //开启线程
        Runnable runnable = new Runnable() { // 利用Runnable开启线程
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "创建线程2");
            }
        };
        new Thread(runnable).start(); //开启线程
    }

(三)、函数式(Function)接口

1.函数式接口概述

什么是函数式(Functional)接口

函数式接口就是只有一个方法的接口,同时,只有函数式接口可以使用Lambda表达式

在java.util.function包下定义了Java 8 的丰富的函数式接口

Java当中的lambda是函数式编程吗

在函数式编程语言当中,Lambda表达式的类型是函数。在Java8中,Lambda表达式是对象,而不是函数,它们必须依附于一类特别的对象类型——函数式接口。

2.经典函数式接口

Runnable接口就是一个典型的函数式接口,在上面创建线程的时候也用到了,他是可以用 匿名内部类 的形式进行实例化的。

Runable是一个典型的函数式接口

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}
new Thread(()-> System.out.println(Thread.currentThread().getId()+"<-当前的线程名字")).start();
        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getId());
        };

3.自定义函数式接口

package com.example.springboot01hello.dao;
@FunctionalInterface //表明我们这里是函数式接口,可设可不设。设置的话会提升性能
public interface interface1 {
    void show();
}

函数式接口中使用泛型:

package com.example.springboot01hello.dao;
@FunctionalInterface //表明我们这里是函数式接口,可设可不设。设置的话会提升性能
public interface interface1<T> {
    public  T show(T t);
}

4.@FunctionlInterface用法

  1. 该注解只能标记在"有且仅有一个方法"的接口上,表示函数式接口。
  2. 该注解不是必须的,如果一个接口符合"函数式编程"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查,如果编写的不是函数式接口,但是加上了@Functionallnterface 那么编译器会报错
  3. 在函数式接口使用该注解,javadoc 也会包含一条声明,说明这个接口是一个函数式接口

5.四大核心函数式接口

特别重要!!!

6.其他函数式接口

(四)、Lambda表达式

1. Lambda表达式概述

Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更灵活的代码

Lambda表达式 和 函数式接口 的关系

Lambda表达式就是一个函数式接口的实例(注意是实例,Object a = new Object()这个a只是个引用变量,而new Object这是一个实例)。只要一个对象是函数式接口的实例,那么该对象就可以用Lambda表达式来表示

Lambda表达式 和 匿名内部类 的关系

函数式接口是可以使用匿名内部类进行创建实例,而lambda可以简化使用匿名内部类创建

注意: 使用lambda简化匿名内部类的前提条件是,接口必须是函数式接口。而匿名内部类创建实例却不一定非得是函数式接口,甚至都不一定是接口,还可以是普通类。

匿名内部类、函数式接口、lambda表达式 这三个关系一定要搞清楚。

2.Lambda 语法

Lambda 表达式:在Java 8 语言中引入的一种新的语法元素和操作符。这个操作符

为 “->” , 该操作符被称为 Lambda 操作符或箭头操作符。它将 Lambda 分为两个部分:

  1. 左侧:指定了 Lambda 表达式需要的参数列表
  2. 右侧:指定了 Lambda 体,是抽象方法的实现逻辑,也即Lambda表达式要执行的功能。

3.匿名内部类 转换 Lambda

从匿名类到 Lambda 的转换举例1:

通过下面示例我们能发现一个问题:使用匿名内部类,没有变量引用也可以创建,而lambda则不可以,他必须要有变量引用。这个变量引用可以是直接的变量引用,也可以是方法内参数传递,Lambda表达式就是一个函数式接口的实例

注意俩字 “实列”!!!!!!

假如没有变量引用例如:

() -> System.out.println("我是一个函数式"); 只有这个肯定是不行的,需要靠前面的TestInterface变量引用来做类型推断。

@Test
    public void test3() {
        interface1 interface0 = new interface1() {
            @Override
            public void show() {
                System.out.println("我是匿名内部类函数");
            }
        };
        interface0.show();
        interface1 interface2 = () -> {
            System.out.println("我是Lambda表达式");
        };
        interface2.show();
    }

4.匿名内部类 转换 Lambda 2

通过下面这个示例会发现,他其实就是在不断的优化,尽可能的让我们开发人员少写代码。他是如何做到一步一步省略的?其实这就是Java语法糖

@Test
    public void test3() {
        // 1.匿名内部类创建线程
        Runnable runnable = new Runnable() { // 利用Runnable开启线程
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "创建线程1");
            }
        };
        new Thread(runnable).start(); //开启线程
        // 2.省去Runnable变量,等同于上方
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "创建线程2");
            }
        }).start(); //开启线程
        // 3.使用Lambda表达式,实现多线程,省去了new Runnable和重写的方法名字
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "创建线程3");
        }).start();
        // 4.优化Lambda,去掉大括号
        new Thread(() ->  System.out.println(Thread.currentThread().getName() + "创建线程3")).start();
    }

5.Lambda语法格式

代码说明:使用Lambda表达式。一般的格式是()-> 0,如果0里面只有一行代码,则0可以省略。

->左边的()表示参数列表,如果有形参,则在()中添加形参,->右边0表示具体逻辑。如果方法体返回值是void,则甚至可以在0中不写任何逻辑(当然也要结合场景)。返回值如果有值,则需要写具体的逻辑, return处理后的值。

相关文章
|
6天前
|
云安全 人工智能 算法
以“AI对抗AI”,阿里云验证码进入2.0时代
三层立体防护,用大模型打赢人机攻防战
1359 7
|
3天前
|
存储 弹性计算 应用服务中间件
2026年阿里云服务器新手租用全流程完整步骤教程(最新版)
2026年阿里云服务器新手租用全流程完整步骤教程,阿里云服务器提供自定义租用、一键租用、云市场租用和活动租用四种核心方式,适配不同配置需求、技术能力和预算场景。无论是需要精准配置的专业用户,还是追求快速部署的新手,都能找到合适的租用方案。以下是详细的适用场景和操作流程,助力高效上云。
288 148
|
7天前
|
人工智能 Rust 运维
这个神器让你白嫖ClaudeOpus 4.5,Gemini 3!还能接Claude Code等任意平台
加我进AI讨论学习群,公众号右下角“联系方式”文末有老金的 开源知识库地址·全免费
|
3天前
|
人工智能 弹性计算 运维
2026年阿里云建站费用解读:三种方案价格明细、功能特性及选型建议
阿里云建站费用多少?2026年阿里云建站费用解读:三种方案价格明细、功能特性及选型建议。在数字化需求日益增长的当下,搭建网站成为个人展示、企业推广的重要途径。阿里云作为主流云服务提供商,针对不同技术基础与业务规模,推出 “自购服务器建站”“万小智 AI 模板建站”“云企业官网定制建站” 三种核心方案,价格从 38 元 / 年到数万元 / 年不等,覆盖从个人到中大型企业的全场景需求。本文基于今年最新官方定价与实测数据,从方案细节、价格体系、功能对比、场景适配等维度展开解析,为用户提供客观选型参考。
258 154
|
6天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
832 4
|
13天前
|
编解码 人工智能 自然语言处理
⚽阿里云百炼通义万相 2.6 视频生成玩法手册
通义万相Wan 2.6是全球首个支持角色扮演的AI视频生成模型,可基于参考视频形象与音色生成多角色合拍、多镜头叙事的15秒长视频,实现声画同步、智能分镜,适用于影视创作、营销展示等场景。
846 14
|
1天前
|
机器学习/深度学习 人工智能 算法
炎鹊「Nexus Agent V1.0」:垂直领域AI应用的原生能力引擎
炎鹊AI「Nexus Agent V1.0」是垂直行业专属AI原生引擎,融合大模型、AIGA决策大脑、行业知识图谱与专属模型,打造“感知-决策-执行”闭环。支持21个行业低代码构建工具型、员工型、决策型AI应用,实现技术到业务价值的高效转化,推动AI从实验走向规模化落地。(239字)
192 1