Lambda表达式学习笔记

导读:本篇文章讲解 Lambda表达式学习笔记,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

Lambda表达式

一、Lambda表达式简介

什么是Lambda?

Lambda是JAVA 8添加的新特性,说白了,Lambda是一个匿名函数

为什么使用Lambda

使用Lambda表达式可以对一个接口的方法进行非常简洁的实现

这里写一个小型测试:

我们如果想要实现一个接口是有三种方法的!

1:使用接口实现类

  • 举个例子现在有一个接口:

interface Comparator{
    int compare(int a,int b);
}

然后我们写一个实现类来继承这个接口:

class MyComparator implements  Comparator{


    @Override
    public int compare(int a, int b) {
        return a-b;
    }
}

然后我们在主方法中调用:这样实现了a-b这个功能

 Comparator comparator = new MyComparator();

2:使用匿名内部类

还是上面的这个例子我们在主方法中这样写:

  Comparator comparator1 = new Comparator() {
            @Override
            public int compare(int a, int b) {
                return a-b;
            }
        };

3:使用lambda表达式:

   Comparator comparator2 =(a,b) -> a-b;

通过比较发现第三种代码最少了!

Lambda对接口的要求

虽然可以使用Lambda表达式对某些接口进行简单的实现,但是并不是所有的接口都可以用Lambda表达式来实现,要求接口中定义的必须要实现的抽象方法只能是一个

在JAVA8中 ,对接口加了一个新特性:default
可以使用default对接口方法进行修饰,被修饰的方法在接口中可以默认实现

@FunctionalInterface

修饰函数式接口的,接口中的抽象方法只有一个

二、Lambda的基础语法

1.语法

// 1.Lambda表达式的基础语法
// Lambda是一个匿名函数 一般关注的是以下两个重点
// 参数列表 方法体

/**
* ():用来描述参数列表
*  {}:用来描述方法体 有时可以省略
*  ->: Lambda运算符 读作goes to
*  例 Test t=()->{System.out.println("hello word")}; 大括号可省略
*/

2.创建多个接口

/**
 * 无参数无返回值接口
 * @author Alan
 * @version 1.0
 * @date 2020-05-27 10:24
 */
@FunctionalInterface
public interface LambdaNoneReturnNoneParmeter {

    void test();
}

/**
 * 无返回值有单个参数
 * @author Alan
 * @version 1.0
 * @date 2020-05-27 10:26
 */
@FunctionalInterface
public interface LambdaNoneReturnSingleParmeter {

    void test(int n);
}

/**
 * 无返回值 多个参数的接口
 * @author Alan
 * @version 1.0
 * @date 2020-05-27 10:27
 */
@FunctionalInterface
public interface LambdaNoneReturnMutipleParmeter {

    void test(int a,int b);
}

/**
 * 有返回值 无参数接口
 * @author Alan
 * @version 1.0
 * @date 2020-05-27 10:28
 */
@FunctionalInterface
public interface LambdaSingleReturnNoneParmeter {

    int test();
}

/**
 * 有返回值 有单个参数的接口
 * @author Alan
 * @version 1.0
 * @date 2020-05-27 10:29
 */
@FunctionalInterface
public interface LambdaSingleReturnSingleParmeter {

    int test(int n);
}

/**
 * 有返回值 有多个参数的接口
 * @author Alan
 * @version 1.0
 * @date 2020-05-27 10:30
 */
@FunctionalInterface
public interface LambdaSingleReturnMutipleParmeter {

    int test(int a,int b);
}

3.创建测试类

package com.alan.learn.syntax;

import com.alan.learn.interfaces.*;

/**
 * @author Alan
 * @version 1.0
 * @date 2020-05-27 10:33
 */
public class Syntax1 {

    public static void main(String[] args) {
        // 1.Lambda表达式的基础语法
        // Lambda是一个匿名函数 一般关注的是以下两个重点
        // 参数列表 方法体

        /**
         * ():用来描述参数列表
         *  {}:用来描述方法体
         *  ->: Lambda运算符 读作goes to
         */

        // 无参无返回  
        LambdaNoneReturnNoneParmeter lambda1=()->{
            System.out.println("hello word");
        };
        lambda1.test();

        // 无返回值 单个参数 
        LambdaNoneReturnSingleParmeter lambda2=(int n)->{
            System.out.println("参数是:"+n);
        };
        lambda2.test(10);

        // 无返回值 多个参数
        LambdaNoneReturnMutipleParmeter lambda3=(int a,int b)->{
            System.out.println("参数和是:"+(a+b));
        };
        lambda3.test(10,12);

        // 有返回值 无参数
        LambdaSingleReturnNoneParmeter lambda4=()->{
            System.out.println("lambda4:");
            return 100;
        };
        int ret=lambda4.test();
        System.out.println("返回值是:"+ret);

        // 有返回值 单个参数
        LambdaSingleReturnSingleParmeter lambda5=(int a)->{
            return a*2;
        };
        int ret2= lambda5.test(3);
        System.out.println("单个参数,lambda5返回值是:"+ret2);

        //有返回值 多个参数
        LambdaSingleReturnMutipleParmeter lambda6=(int a,int b)->{
            return a+b;
        };
        int ret3=lambda6.test(12,14);
        System.out.println("多个参数,lambda6返回值是:"+ret3);
    }
}

输出结果:
    hello word
	参数是:10
	参数和是:22
	lambda4:
	返回值是:100
	单个参数,lambda5返回值是:6
    多个参数,lambda6返回值是:26

三、语法精简

针对上述基础语法的精简

1.参数类型精简

/**
* 语法精简
* 1.参数类型
* 由于在接口的抽象方法中,已经定义了参数的数量类型 所以在Lambda表达式中参数的类型可以省略
* 备注:如果需要省略类型,则每一个参数的类型都要省略,千万不要一个省略一个不省略
*/
LambdaNoneReturnMutipleParmeter lambda1=(int a,int b)-> {
    System.out.println("hello world"); 
};    
可以精简为:
LambdaNoneReturnMutipleParmeter lambda1=(a,b)-> {
    System.out.println("hello world");
};

2.参数小括号精简

/**
* 2.参数小括号
* 如果参数列表中,参数的数量只有一个 此时小括号可以省略
*/
LambdaNoneReturnSingleParmeter lambda2=(a)->{
    System.out.println("hello world");
};
可以精简为:
LambdaNoneReturnSingleParmeter lambda2= a->{
    System.out.println("hello world");
};

3.方法大括号精简

/**
* 3.方法大括号
* 如果方法体中只有一条语句,此时大括号可以省略
*/
LambdaNoneReturnSingleParmeter lambda3=a->{
    System.out.println("hello world");
};
可以精简为:
LambdaNoneReturnSingleParmeter lambda3=a->System.out.println("hello world");

4.大括号精简补充

/**
* 4.如果方法体中唯一的一条语句是一个返回语句
* 贼省略大括号的同时 也必须省略return
*/
LambdaSingleReturnNoneParmeter lambda4=()->{
    return 10;
};
可以精简为:
LambdaSingleReturnNoneParmeter lambda4=()->10;

5.多参数,有返回值 精简

LambdaSingleReturnNoneParmeter lambda4=(a,b)->{    return a+b;};可以精简为:LambdaSingleReturnMutipleParmeter lambda5=(a,b)->a+b;

精简语法:

public class Syntax2 {
    //语法精简
    //1. 参数类型
    // 要么都省略掉,要么不省略
    LambdaNoneReturnManyParameter lambda1 = (a, b)->{
        System.out.println("lambda1");
    };
    //2. 参数列表
    // 参数的类型只有一个,此时小括号可以省略
    LambdaNoneReturnSingleParameter lambda2 = a ->{
        System.out.println("lambda2");
    };
    //3. 大括号省略
    // 方法体中只有一条语句时
    LambdaNoneReturnSingleParameter lambda3 = a -> System.out.println("lambda3");
    //4. 如果方法体中的唯一语句时返回语句,可以省略return
    LambdaSingleReturnNoneParameter lambda4 = () -> 10;
    LambdaSingleReturnSingleParameter lambda5 = a -> a;
    LambdaSingleReturnManyParameter lambda6 = (a,b)-> a+b;

}

集合排序:

import java.util.ArrayList;

public class exercise1 {
    public static void main(String[] args) {
        //集合排序
        //ArrayList<>
        //需求:一个list中有若干个person,按照年龄降序排序
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("jack",10));
        list.add(new Person("lisa",23));
        list.add(new Person("jie",23));
        list.add(new Person("dd",13));
        list.add(new Person("lun",14));
        list.add(new Person("shun",12));
        list.add(new Person("hao",15));
        list.add(new Person("zhu",16));
        //排序
        list.sort((o1,o2)->{
            return o1.age - o2.age;
        });
        //简化
        list.sort((o1,o2)-> o1.age-o2.age);
        System.out.println(list);

    }
}

TreeSet 排序:

import java.util.TreeSet;

public class exercise2 {
    public static void main(String[] args) {
//        TreeSet   实现降序
//        TreeSet<Person> set = new TreeSet<>();
//        set.add(new Person("jack",10));
//        set.add(new Person("lisa",23));
//        set.add(new Person("jie",23));
//        set.add(new Person("dd",13));
//        set.add(new Person("lun",14));
//        set.add(new Person("shun",12));
//        set.add(new Person("hao",15));
//        set.add(new Person("zhu",16));
//		  System.out.println(set); 抛出异常,不知道按照哪个元素排序,分不清谁大谁小
        //方法一:实现Comparable接口中的方法,自然排序。例如一个数字的集合
        //方法二:使用lambada表达式实现Comparator,定制排序。例如一个对象的集合
        TreeSet<Person> set2 = new TreeSet<>(((o1, o2) -> o1.age - o2.age));
        set2.add(new Person("lisa", 23));
        set2.add(new Person("jie", 23));
        set2.add(new Person("dd", 13));
        set2.add(new Person("lun", 14));
        set2.add(new Person("shun", 12));
        set2.add(new Person("hao", 15));
        set2.add(new Person("zhu", 16));
        System.out.println(set2);
        //出现相同年龄的只保留一个

        //可以重写排序规则
        TreeSet<Person> set3 = new TreeSet<>((o1, o2) -> {
            if (o1.age >= o2.age){
                return -1;
            }else {
                return 1;
            }
        });
        set3.add(new Person("lisa", 23));
        set3.add(new Person("jie", 23));
        set3.add(new Person("dd", 13));
        set3.add(new Person("lun", 14));
        set3.add(new Person("shun", 12));
        set3.add(new Person("hao", 15));
        set3.add(new Person("zhu", 16));
        System.out.println(set3);
    }
}

线程实例化:

public class exercise5 {
    public static void main(String[] args) {
        //需求:开辟一个线程,输出数字,开辟一个线程可以通过继承Thread或者实现Runnable接口
        //可以使用匿名内部类或者实现Runnable接口
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        });
        t.start();
        //使用lambda,Runnable是一个无参无返回的FunctionalInterface接口
        Thread t2 = new Thread(()-> System.out.println("hello lambda"));
        t2.start();
    }
}

请添加图片描述

消费型接口:

@Test
public void test01(){
    //Consumer
    Consumer<Integer> consumer = (x) -> System.out.println("消费型接口" + x);
    //test
    consumer.accept(100);
} 

提供型接口

@Test
public void test02(){
    List<Integer> list = new ArrayList<>();
    List<Integer> integers = Arrays.asList(1,2,3); 
    list.addAll(integers);
    //Supplier<T>
    Supplier<Integer> supplier = () -> (int)(Math.random() * 10);
    list.add(supplier.get());
    System.out.println(supplier);
    for (Integer integer : list) {
        System.out.println(integer);
    }
}

函数型接口:

@Test
public void test03(){
    //Function<T, R>
    String oldStr = "abc123456xyz";
    Function<String, String> function = (s) -> s.substring(1, s.length()-1);
    //test
    System.out.println(function.apply(oldStr));
}

断言型接口:

@Test
public void test04(){
    //Predicate<T>
    Integer age = 35;
    Predicate<Integer> predicate = (i) -> i >= 35;
    if (predicate.test(age)){
        System.out.println("你该退休了");
    } else {
        System.out.println("我觉得还OK啦");
    }
}

任务练习:

修改线程:

package 函数式编程;


import java.io.IOException;

/**
 * @author ${范涛之}
 * @Description
 * @create 2021-12-01 14:23
 */
public class Test2 {


    public static void main(String[] args) {
        new Thread(() -> {
            synchronized ("lock"){
            System.out.println("t1线程开始");
                "lock".notify();
                System.out.println("t1 线程结束");
        }}).start();

       Thread thread1  = new Thread(() ->{
               synchronized ("lock1") {
                   System.out.println("t2线程开始");
                   "lock1".notify();
                   System.out.println("t2线程结束");
               }});
       thread1.start();


       }
    }





运行结果:

请添加图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/81038.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!