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处理后的值。

相关文章
面试官: 请你手写一份 Call()源码,看完此篇不用担心!
面试官: 请你手写一份 Call()源码,看完此篇不用担心!
|
7月前
|
UED
面试题7:你写的bug别人都看不懂怎么办?
面试题7:你写的bug别人都看不懂怎么办?
面试题7:你写的bug别人都看不懂怎么办?
|
Java 编译器
101.【用了Optional,同事都表示看不懂!】(三)
101.【用了Optional,同事都表示看不懂!】
50 0
|
Java API 容器
101.【用了Optional,同事都表示看不懂!】(一)
101.【用了Optional,同事都表示看不懂!】
102 0
|
Python Windows
你真的看得懂报错吗?
你真的看得懂报错吗?
320 0
你真的看得懂报错吗?
|
小程序 Java
Java 8 排序的 10 个姿势,太秀了吧!同事直呼看不懂。。
Java 8 排序的 10 个姿势,太秀了吧!同事直呼看不懂。。
214 0
Java 8 排序的 10 个姿势,太秀了吧!同事直呼看不懂。。
|
存储 Java
来自三段代码的疑惑~
来自三段代码的疑惑~
116 0
|
JSON 前端开发 Java
我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。
我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。
164 0
我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。
|
NoSQL Java 程序员
JDK的equals方法都写错了,那到底该怎么写呢?(备战2022春招或暑期实习,每天进步一点点,打卡100天,Day3)
JDK的equals方法都写错了,那到底该怎么写呢?(备战2022春招或暑期实习,每天进步一点点,打卡100天,Day3)
116 0
JDK的equals方法都写错了,那到底该怎么写呢?(备战2022春招或暑期实习,每天进步一点点,打卡100天,Day3)
|
SQL JSON 自然语言处理
Code Review 是苦涩但有意思的修行
孤尽,阿里巴巴高级技术专家,《阿里巴巴 Java 开发手册》、《码出高效》的作者。本文将分享孤尽老师对于团队 CodeReview 的一些看法和心得。
12593 0
Code Review 是苦涩但有意思的修行