当前位置:   article > 正文

java的lambda表达式_java lambda中可以抛出异常吗

java lambda中可以抛出异常吗

lambda表达式的格式

以->分隔,前边是参数列表,后边是表达式体也就是具体要执行得到逻辑。
根据参数列表的个数有无返回值等可以分为6种形式,这个不必多说。
在这里插入图片描述

lambda表达式依赖函数式接口

lambda表达式依赖于函数式接口,即只有一个抽象方法的接口。个人理解表达式体就是实现那个唯一抽象方法的。也就是创建了一个实现这个接口的一个对象。需要注意的是,若 Lambda 表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明,也就是lambda表达式里不能抛出异常,或者try/catch。
我们可以在任意函数式接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。
在这里插入图片描述

Java内置的四大函数式接口

在这里插入图片描述

@Test
    public void test6() {
        Supplier<String> supplier = ()->"532323".substring(0, 2);
        System.out.println(supplier.get());
    }
    @Test
    public void test7() {
        Function<String, String> function = (x)->x.substring(0, 2);
        System.out.println(function.apply("我是中国人"));
    }
    @Test
    public void test8() {
        Predicate<String> predicate = (x)->x.length()>5;
        System.out.println(predicate.test("12345678"));
        System.out.println(predicate.test("123"));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

运行结果:
在这里插入图片描述

关于lambda表达式里不能抛出受查异常问题

首先,运行时异常可以抛出,因为运行时异常编译器不管,只有在程序运行时发生后直接挂掉程序就行。但是受查异常编译器要求必须处理,否则编译不通过,要么try/catch掉要么向上抛让,但是lambda里不能向上抛,原因是lambda表达式本质是执行了函数式接口里的那个唯一抽象方法,如果这个方法抛异常那么这个接口也要抛异常,但是这个接口源码是不能改的,也就是不能抛出去异常。如果你自己定义的函数接口那个抽象方法抛出了异常,那么lambda表达式就可以抛异常。

自己写的例子

package com.company.java8.lambda;
@FunctionalInterface
public interface ConsumerInterface <T>{
    void accept(T t);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
package com.company.java8.lambda;


import java.util.List;

public class TestStream<T> {
    private List<T> list;
    public void myForEach(ConsumerInterface<T> sonsumer){
        for(T t:list){
            sonsumer.accept(t);
        }
    }
    public void setList(List<T> list){
        this.list=list;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
package com.company.java8.lambda;

import java.util.Arrays;
import java.util.List;

public class Test {
    public static void main(String[] args){
        TestStream<String> stream = new TestStream<String>();
        List list = Arrays.asList("11","22","33");
        stream.setList(list);
        stream.myForEach(str -> {System.out.println(str);
           // 只有函数式接口里的方法抛出异常,这里才能抛出异常
       //相当于在这里重写了accept方法
        });
    }
}



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

``
运行结果:
在这里插入图片描述

又一个例子

public interface Cook {
    void makeFood();
    }
  • 1
  • 2
  • 3
public class Demo05InvokeCook {
    public static void main(String[] args) {
        // TODO 请在此使用Lambda【标准格式】调用invokeCook方法
         invokeCook(()> {
       System.out.println("吃饭啦!");  
    });
    }
    private static void invokeCook(Cook cook) {
        cook.makeFood();
    }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

又又又一个例子

public class Person {
    private String name;
    private int age;
   
    // 省略构造器、toString方法与Getter Setter
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

传统写法
如果使用传统的代码对 Person[] 数组进行排序,写法如下:

public class Demo06Comparator {
    public static void main(String[] args) {
       // 本来年龄乱序的对象数组  
        Person[] array = {
         new Person("古力娜扎", 19),    
         new Person("迪丽热巴", 18),    
        new Person("马尔扎哈", 20) };     
       // 匿名内部类  
        Comparator<Person> comp = new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge() ‐ o2.getAge();
            }
        };
        Arrays.sort(array, comp); // 第二个参数为排序规则,即Comparator接口实例
        for (Person person : array) {
            System.out.println(person);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

下面我们来搞清楚上述代码真正要做什么事情。
为了排序, Arrays.sort 方法需要排序规则,即 Comparator 接口的实例,抽象方法 compare 是关键;
为了指定 compare 的方法体,不得不需要 Comparator 接口的实现类;
为了省去定义一个 ComparatorImpl 实现类的麻烦,不得不使用匿名内部类;
必须覆盖重写抽象 compare 方法,所以方法名称、方法参数、方法返回值不得不再写一遍,且不能写错;
实际上,只有参数和方法体才是关键。
说白了就是我要执行一个函数式接口里的方法,甭new对象啥的啦,直接需要的地方重写方法得了。
Lambda写法

public class Demo07ComparatorLambda {
    public static void main(String[] args) {
        Person[] array = {
           new Person("古力娜扎", 19),  
           new Person("迪丽热巴", 18),  
           new Person("马尔扎哈", 20) };  
        Arrays.sort(array, (Person a, Person b)> {
           return a.getAge() ‐ b.getAge();  
        });
        for (Person person : array) {
            System.out.println(person);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

再来一个例子吧

@FunctionalInterface
public interface ConInterface2 {
     void doSom(List d);
}
  • 1
  • 2
  • 3
  • 4
package com.company.java8.lambda;

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

public class MainTest {
    public static void main(String[] args) {
        List<String> a = new ArrayList();
        a.add("aaa");
        a.add("bbb");
        //方式一
        ConInterface2 cif = (gg) -> System.out.println(gg.get(1));
        cif.doSom(a);

        //方式二
        bb(a,(List q) -> {
            System.out.println(q.get(1));
        });
    }
         private static void bb(List w,ConInterface2 c2){
             c2.doSom(w);
         }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

运行结果

bbb
bbb
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/294406
推荐阅读
相关标签
  

闽ICP备14008679号