Java8-Lambda表达式

Java8-Lambda表达式

记录个人学习过程,参考https://www.bilibili.com/video/BV1ci4y1g7qD?p=1,侵删

通过Lambda表达式可以替代以前常写的匿名内部类来实现接口,Lambda表达式本质上是一个匿名函数。

入门实例

package com.company;

public class Program {
    public static void main(String[] args) {
        /**不使用lambda表达式
         * */
//        Cal c = new Cal() {
//            @Override
//            public int add(int a, int b) {
//                return a+b;
//            }
//        };


        /** 使用lambda表达式
         * ()为参数列表
         * {}为方法体
        */
        Cal c = (int a,int b) -> {return a+b;};

        System.out.println(c.add(2,3));
    }
    interface Cal{
        int add(int a,int b);
    }
}

Lambda表达式语法

这个Lambda表达式:

(int a,int b) -> {return a+b;}

本质上是一个函数,而

一般的函数类似

int add(int a,int b){
	return a+b;
}

一般的函数有返回值,方法名,参数列表,方法体

而Lambda表达式只有参数列表和方法体

说明:

():用于描述参数列表

{}:用于描述方法体

->:Lambda运算符,可以叫做箭头符号,或goes to

Lambda表达式语法实例

package com.company;

public class Program2 {
    public static void main(String[] args) {
        If1 if1 = ()->{
            System.out.println("无参数无返回值");
        };
        if1.test();

        If2 if2 = (int a)->{
            System.out.println("单个参数无返回值,a:"+a);
        };
        if2.test(12);

        If3 if3 = (int a,int b)->{
            System.out.println("两个参数无返回值,a+b:"+(a+b));
        };
        if3.test(12,3);

        If4 if4 = ()->{
            return 1;
        };
        System.out.println("无参数有返回值"+if4.test());

        If5 if5 = (int a)->{
            return a;
        };
        System.out.println("单个参数有返回值"+if5.test(25));

        If6 if6 = (int a,int b)->{
            return a+b;
        };
        System.out.println("两个参数有返回值"+if6.test(25,37));
    }
    interface If1{
        /**无参数无返回值
         * */
        void test();
    }
    interface If2{
        /**单个参数无返回值
         * */
        void test(int a);
    }
    interface If3{
        /**两个参数无返回值
         * */
        void test(int a,int b);
    }
    interface If4{
        /**无参数有返回值
         * */
        int test();
    }
    interface If5{
        /**单个参数有返回值
         * */
        int test(int a);
    }
    interface If6{
        /**两个参数有返回值
         * */
        int test(int a,int b);
    }
}

Lambda表达式精简语法

注意点:

  1. 参数类型可以省略
  2. 若只有一个参数,()可以省略
  3. 若方法体只有一条语句,{}可以省略
  4. 若方法体中唯一的语句是return返回语句,则省略大括号的同时也要省略return
package com.company;

public class Program3 {
    public static void main(String[] args) {
        If1 if1 = ()-> System.out.println("无参数无返回值");
        if1.test();

        If2 if2 = a->System.out.println("单个参数无返回值,a:"+a);
        if2.test(12);

        If3 if3 = ( a,b)->System.out.println("两个参数无返回值,a+b:"+(a+b));
        if3.test(12,3);

        If4 if4 = ()-> 1;

        System.out.println("无参数有返回值"+if4.test());

        If5 if5 = a->a;
        System.out.println("单个参数有返回值"+if5.test(25));

        If6 if6 = (a,b)->a+b;
        System.out.println("两个参数有返回值"+if6.test(25,37));
    }
    interface If1{
        /**无参数无返回值
         * */
        void test();
    }
    interface If2{
        /**单个参数无返回值
         * */
        void test(int a);
    }
    interface If3{
        /**两个参数无返回值
         * */
        void test(int a,int b);
    }
    interface If4{
        /**无参数有返回值
         * */
        int test();
    }
    interface If5{
        /**单个参数有返回值
         * */
        int test(int a);
    }
    interface If6{
        /**两个参数有返回值
         * */
        int test(int a,int b);
    }
}

方法引用

当多个Lambda表达式的实现函数是一样的时候,可以封装成通用方法,以便于维护;

用方法引用实现:

语法如下:

对象::方法

如果是static方法可以直接 类名::方法

package com.company;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

public class Program4 {
    public static void main(String[] args) {

        If5 if5 = Program4::testB;
        System.out.println("testB:"+if5.test(6));

        Program4 program4 = new Program4();
        If5 if51 =  program4::testA ;
        System.out.println("testA:"+if51.test(9));
    }
    public int testA(int a){
        return a-2;
    }
    public  static int testB(int a){
        return a-2;
    }
    interface If5{
        /**单个参数有返回值
         * */
        int test(int a);
    }

}

构造方法引用

如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用

语法:类名::new

实例:

package com.company;

public class Program5 {
    public static void main(String[] args) {
        //DogService1 dogService1 = ()->new Dog();
        //System.out.println(dogService1.getDog());

        DogService1 dogService11 = Dog::new;
        System.out.println(dogService11.getDog());

        DogService2 dogService2 = Dog::new;
        System.out.println(dogService2.getDog("Tom",2));

    }
    interface DogService1{
        Dog getDog();
    }
    interface DogService2{
        Dog getDog(String name, int age);
    }
}

综合实例

package com.company;

import java.util.ArrayList;
import java.util.List;

public class Program6 {
    public static void main(String[] args) {
        List<Dog> list = new ArrayList<>();
        list.add(new Dog("a",4));list.add(new Dog("f",3));
        list.add(new Dog("b",1));list.add(new Dog("e",4));
        list.add(new Dog("c",2));list.add(new Dog("d",2));

        System.out.println("lambda表达式集合排序");
        list.sort(((o1, o2) -> {return o1.getAge()- o2.getAge();}));
//        System.out.println(list);
        list.forEach(System.out::println);
    }

}

@FunctionalInterface注解

前面我们会发现Consumer接口,Comparator接口都有
@FunctionalInterface注解;
这个注解是函数式接口注解,所谓的函数式接口,当然首先是一个接口,然后就是在这个
接口里面只能有一个抽象方法。
这种类型的接口也称为SAM接口,即Single Abstract Method interfaces

特点

  • 接口有且仅有一个抽象方法
  • 允许定义静态方法
  • 允许定义默认方法
  • 允许java.lang. Object中的public方法
  • 该注解不是必须的,如果一个接口符合”函数式接口"定义,那么加不加该注解都没有影
    响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加
    上了@FunctionInterface , 那么编译器会报错
package com.company;

//正确的函数式接口
@FunctionalInterface
public interface TestInterface {
    //抽象方法
    public void sub();

    // java.lang.Object中的pub1ic方法
    public boolean equals(Object var1);

    //默认方法
    public default void defaultMethod() {
    }

    //静态方法
    public static void staticMethod() {
    }
}
//错误的函数式接口(有多个轴象方法)
@FunctionalInterface
    public interface TestInterface2{
        void add();
        void sub();
}

系统内置函数式接口

Java8的推出,是以Lambda重要特性,一起推出的,其中系统内置了一系列函数式接口
在jdk的java . util.function包下,有一系列的内置函数式接口

Java内置的四大核心函数式接口

函数式接口参数类型返回类型用途
Consumer消费型接口Tvoid对类型为T的对象应用操作,包含方法:void accept(T t)
Supplier供给型接口T返回类型为T的对象,包含方法:T get()
Function<T,R>函数型接口TR对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法: R apply(T t)
Predicate断定型接口Tboolean确定类型为T的对象是否满足某约束,并返回boolean值。包含方法:boolean test(T t)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值