Lambda 表达式

本文介绍了Java8中的Lambda表达式,包括其概述、语法示例、函数式接口的使用,以及方法引用和对象引用的概念。Lambda表达式简化了代码,通过箭头操作符将参数列表和操作体分开。函数式接口是Lambda表达式的基础,例如消费型、供给型、函数型和断言型接口。此外,还探讨了方法引用的不同形式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、概述

Java8中引入了一个新的操作符"->” 该操作符称为箭头操作符或Lambda 操作符。

箭头操作符将Lambda表达式拆分成两部分:
左侧: Lambda表达式的参数列表;
右侧: Lambda表达式中所需执行的功能,即Lambda体。

2、语法举栗

2.1 无参数,无返回值

 @Test
    public void test(){
        int num=3;
        Runnable runnable=()->System.out.println("Hello Lambda"+num);
        runnable.run();
    }

2.2 有一个参数,无返回值

此时只有一个参数,参数(x) 的括号可以省略不写

    @Test
    public void test1(){
        List<String> list=new ArrayList<>();
        // 参数(x) 的括号省略不写
        //  Consumer<String> consumer=(x) ->list.add(x);
        Consumer<String> consumer=x ->list.add(x);
        consumer.accept("aaa");
        consumer.accept("bbb");
        list.forEach(System.out::println);
    }

2.3 有两个以上的参数,有返回值,并且Lambda体中有多条语句

    @Test
    public void test2(){
        Comparator<Integer> comparator=(x,y)->{
            System.out.println("x为:"+x);
            System.out.println("y为:"+y);

            return Integer.compare(x,y);
        };

        System.out.println(comparator.compare(1,2));
    }

2.4 Lambda体中只有一条语句,return 和大括号都可以省略不写

Lambda表达式的参数列表的数据类型是可以省略不写的。因为JVM编译器可以通过上下文推断出数据类型,也就是’类型推断’。

    @Test
    public void test3(){
    	// 参数类型可省略
    	// Comparator<Integer> comparator=(Integer x,Integer y)->Integer.compare(x,y);
        Comparator<Integer> comparator=(x,y)->Integer.compare(x,y);
        System.out.println(comparator.compare(1,2));
    }

3、函数式接口

3.1 说明

Lambda 表达式需要"函数式接口“的支持。什么是函数式接口?即接口中只有一个抽象方法的接口,可以使用注解@FunctionalInterface进行修饰。注解 @FuncitonalInterface 会限定该接口为函数式接口,即必须有且只有一个抽象方法,否则将无法通过编译。

举个栗子:

自定义函数式接口

@FunctionalInterface
public interface MyCompare<T> {

    int compare(T o1,T o2);
}

实现方法再进行调用

    public int compareImpl(Integer num1, Integer num2, MyCompare<Integer> myCompare){
        return myCompare.compare(num1,num2);
    }

    @Test
    public void testMyCompare(){
        int num=compareImpl(11,2,(x,y)-> Integer.compare(x,y));
        System.out.println(num);
    }

3.2 四大内置核心函数式接口

消费型接口

Consumer<T>
void accept(T t);

举个栗子

    public void consume(Integer integer,Consumer<Integer> consumer){
        consumer.accept(integer);
    }
    
    @Test
    public void testConsumer(){
        consume(100,(x)->System.out.println(x));
    }

供给型接口

Supplier<T>
T get();

举个栗子

    public List<Integer> integerList(int n, Supplier<Integer> supplier){
        List<Integer> numList=new ArrayList<>();
        for(int i=0;i<n;i++){
            numList.add(supplier.get());
        }
        return numList;
    }

    @Test
    public void testSupplier(){
        List<Integer> numList=integerList(5,()->(int)(Math.random()*100));
        for(Integer integer:numList){
            System.out.println(integer);
        }
    }

函数型接口

Function<T, R> 
R app1y(T t);

举个栗子

    public String strHandler(String str, Function<String,String> function){
        return function.apply(str);
    }

    @Test
    public void testFunction(){
        String str=strHandler("hello world!",x->x);
        System.out.println(str);
    }

断言型接口

Predicate<T> 
boolean test(T t);

举个栗子

    public List<String> strFilter(List<String> strList, Predicate<String> predicate){
        List<String> list=new ArrayList<>();
        for(String s:strList){
            if(predicate.test(s)){
                list.add(s);
            }
        }
        return list;
    }

    @Test
    public void testPredicate(){
        List<String> strList=new ArrayList<>();
        List<String> list=strFilter(strList,x->x.length()>5);
        System.out.println(list);
    }

4、方法引用和对象引用

“::”为方法引用运算符,它所在的表达式称为方法的引用。Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致。若Lambda参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName :: method。

方法引用的三种语法格式:

对象: :实例方法名

    @Test
    public void test5(){
        Consumer<String> consumer=(x)->System.out.println(x);
        consumer.accept("hello world!");

        Consumer<String> consumer1=System.out::println;
        consumer.accept("hello China!");
    }

类: :静态方法名

    @Test
    public void test6(){
        Comparator<Integer> comparator=(x,y)->Integer.compare(x,y);
        System.out.println(comparator.compare(1,2));

        Comparator<Integer> comparator1=Integer::compareTo;
        System.out.println(comparator1.compare(1,2));
    }

类: :实例方法名

    @Test
    public void test7(){
        BiPredicate<String,String> biPredicate=(x,y)->x.equals(y);
        System.out.println(biPredicate.test("1","2"));

        BiPredicate<String,String> biPredicate1=String :: equals;
        System.out.println(biPredicate1.test("1","2"));
    }

构造器引用

需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致。下面举个栗子:

public class Cat {

    int age;
    String name;

    public Cat(){
    }

    public Cat(int age){
        this.age=age;
    }
}

    @Test
    public void test8(){
    	// 无参构造
        Supplier<Cat> cat=Cat::new;
		// 有参构造,参数列表一致
        Function<Integer,Cat> catFunction=Cat::new;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值