Lambda表达式

一、简介

什么是Lambda

他是java8新特性,说白了就是一个匿名函数

为什么使用

可以对接口的方法进行非常简洁的实现

对接口的要求

不是所有的都可以使用,要求接口中定义的必须要实现的抽象方法只能是一个

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

@FunctionalInterface

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

二、Lambda基础语法

1.Lambda表达式的基础语法

Lambda是一个匿名函数 一般关注的是以下两个重点

参数列表 方法体

():用来描述参数列表

{}:用来描述方法体 有时可以省略

 ->: Lambda运算符 读作goes to

 例 Test t=()->{System.out.println("hello word")}; 大括号可省略

 2.创建多个接口

/**
 * @Description: 无返回值 多个参数的接口
 */
@FunctionalInterface
public interface LambdaNoneReturnMutipleParmeter {
    void test(int a, int b);
}
/**
 * @Description: 没有返回值没有参数
 */
@FunctionalInterface
public interface LambdaNoneReturnNoneParmeter {
    void test();
}
/**
 * @Description: 无返回值有单个参数
 */
@FunctionalInterface
public interface LambdaNoneReturnSingleParmeter {
    void test(int n);
}
/**
 * @Description: 有返回值 有多个参数的接口
 */
@FunctionalInterface
public interface LambdaSingleReturnMutipleParmeter {
    int test(int a, int b);
}
/**
 * @Description: 有返回值 无参数接口
 */
@FunctionalInterface
public interface LambdaSingleReturnNoneParmeter {
    int test();
}
/**
 * @Description: 有返回值 有单个参数的接口
 */
@FunctionalInterface
public interface LambdaSingleReturnSingleParmeter {
    int test(int n);
}

3.创建测试类

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

//单参无返回
LambdaNoneReturnSingleParmeter lam2=(int a)->{
    System.out.println("单参无返回lam2"+a);
};
lam2.test(10);

//多参无返回
LambdaNoneReturnMutipleParmeter lam3=(int a,int b)->{
    System.out.println("多参无返回lam3:"+(a+b));
};
lam3.test(10,10);

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


//有返回值单个参数
LambdaSingleReturnSingleParmeter lam5=(int a)->{
    return a*2;
};
int test2 = lam5.test(10);
System.out.println("有返回值单个参数lam5:"+test2);

//有返回值 多个参数
LambdaSingleReturnMutipleParmeter lam6=(int a,int b)->{
    return a+b;
};
int test1 = lam6.test(10, 10);
System.out.println("有返回值多个参数lam6:"+test1);

输出结果:

无参无返回lam1:hello
单参无返回lam210
多参无返回lam3:20
有返回值无参数lam4:100
有返回值单个参数lam5:20
有返回值多个参数lam6:20

三、语法精简

1.参数类型精简

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

2.参数小括号精简

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

3.方法大括号精简

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

LambdaNoneReturnSingleParmeter lambda3=a->System.out.println("hello world");

4.大括号精简补充

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

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

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

四、Lambda语法进阶

1.方法引用(普通方法与静态方法)

在实际应用过程中,一个接口在很多地方都会调用同一个实现,例如:

LambdaSingleReturnMutipleParmeter lambda1=(a,b)->a+b;
LambdaSingleReturnMutipleParmeter lambda2=(a,b)->a+b;

这样一来每次都要写上具体的实现方法 a+b,如果需求变更,则每一处实现都需要更改,基于这种情况,可以将后续的是实现更改为已定义的 方法,需要时直接调用就行

/**
 *方法引用:
 * 可以快速的将一个Lambda表达式的实现指向一个已经实现的方法
 * 方法的隶属者 如果是静态方法 隶属的就是一个类  其他的话就是隶属对象
 * 语法:方法的隶属者::方法名
 * 注意:
 *  1.引用的方法中,参数数量和类型一定要和接口中定义的方法一致
 *  2.返回值的类型也一定要和接口中的方法一致
 */
public static void main(String[] args) {
    LambdaSingleReturnSingleParmeter lam1 = a -> a * 2;
    LambdaSingleReturnSingleParmeter lam2 = a -> a * 2;
    //简化
    LambdaSingleReturnSingleParmeter lam3 = a -> change(a);
    //方法引用
    LambdaSingleReturnSingleParmeter lam4=Syntax3::change;
}

private static int change(int a) {
    return a * 2;
}

 2.方法引用(构造方法)

实体类

public class Person {
    public String name;
    public int age;

    public Person() {
        System.out.println("无参构造方法执行了");
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有参构造方法执行了");
    }
}

需求

两个接口,各有一个方法,一个接口的方法需要引用Person的无参构造,一个接口的方法需要引用Person的有参构造 用于返回两个Person对象,例:

interface PersonCreate {
 //通过Person的无参构造实现
    Person getPerson();
}

interface PersonCreate1 {
//通过Person的有参构造实现
    Person getPerson(String name, int age);
}
 public static void main(String[] args) {
        PersonCreate cre = () -> new Person();
        //引用的是Person的无参构造
        //PersonCreater接口的方法指向的是Person的方法
        PersonCreate cre1 = Person::new;
        //实际调用的是Person的无参构造 相当于把接口里的getPerson()重写成new Person()。
        cre1.getPerson();
        //引用的是Person的有参构造
        PersonCreate1 cre2= Person::new;
        Person person = cre2.getPerson("123", 12);
    }

注意:是引用无参构造还是引用有参构造 在于接口定义的方法参数

 五、综合练习

1.集合排序案例

 ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("张三",10));
        list.add(new Person("李四",12));
        list.add(new Person("王五",13));
        list.add(new Person("赵六",14));
        list.add(new Person("李雷",11));
        list.add(new Person("韩梅梅",8));
        list.add(new Person("jack",10));
        System.out.println("排序之前:"+list);
        //将排列的依据传入 具体的方法指向的是 内部元素的age相减 sort会依据结果的正负进行降序排列
        //sort 使用提供的 Comparator对此列表进行排序以比较元素。
        list.sort((o1, o2) -> o2.age-o1.age);
        System.out.println("排序后:"+list);


排序之前:[Person{name='张三', age=10}, Person{name='李四', age=12}, Person{name='王五', age=13}, Person{name='赵六', age=14}, Person{name='李雷', age=11}, Person{name='韩梅梅', age=8}, Person{name='jack', age=10}]
排序后:[Person{name='赵六', age=14}, Person{name='王五', age=13}, Person{name='李四', age=12}, Person{name='李雷', age=11}, Person{name='张三', age=10}, Person{name='jack', age=10}, Person{name='韩梅梅', age=8}]

2.Treeset排序案例

  TreeSet<Person> list = new TreeSet<>((o1, o2) -> {
            if (o2.age <= o1.age) {
                return -1;
            }
            return 1;
        });
        list.add(new Person("张三", 10));
        list.add(new Person("李四", 12));
        list.add(new Person("王五", 13));
        list.add(new Person("赵六", 14));
        list.add(new Person("李雷", 11));
        list.add(new Person("韩梅梅", 8));
        list.add(new Person("jack", 8));
        System.out.println("排序:" + list);


排序:[Person{name='赵六', age=14}, Person{name='王五', age=13}, Person{name='李四', age=12}, Person{name='李雷', age=11}, Person{name='张三', age=10}, Person{name='jack', age=8}, Person{name='韩梅梅', age=8}]

3.集合的遍历

  /**
         * list.forEach(Consumer<? super E> action) 
         * api文档解释: 对 集合中的每个元素执行给定的操作,直到所有元素都被处理或动作引发异常。
         * 将集合中的每一个元素都带入到接口Consumer的方法accept中  然后方法accept指向我们的引用
         * 输出集合中的所有元素
         * list.forEach(System.out::println);
        */

ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,1,2,3,4,5,6,7,8,9);
        list.forEach(integer -> {
            if (integer%2==0){
                System.out.println(integer);
            }
        });

4.删除集合中满足条件的元素

 /**
         * lambda实现
         * 逻辑
         * 将集合中的每一个元素都带入到接口Predicate的test方法中,
         * 如果返回值是true,则删除这个元素
        */
 ArrayList<Person> list=new ArrayList<>();
        list.add(new Person("张三",10));
        list.add(new Person("李四",12));
        list.add(new Person("王五",13));
        list.add(new Person("赵六",14));
        list.add(new Person("李雷",11));
        list.add(new Person("韩梅梅",8));
        list.add(new Person("jack",10));

        list.removeIf(person -> person.age>10);
        System.out.println(list);


[Person{name='张三', age=10}, Person{name='韩梅梅', age=8}, Person{name='jack', age=10}]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值