java8 Lambda表达式和函数式接口

一、Lambda表达式

Lambda表达式其实是一种借鉴,在其他的语言中早已出现。python属于函数式编程思维,Lambda在里面是函数,但是java提倡“万事万物皆对象”,所以在java中,Lambda表达式不是函数而是对象。

Lambda表达式的本质

Lambda的本质是java中接口的一个实例(接口的实现类的具体对象)。可通过下图形象理解。

 Lambda表达式语法

  • 语法

        -> :箭头操作符,Lambda表达式操作符。

        ->左侧:Lambda形参列表,->对应->接口中的抽象方法的形参列表。

        ->右侧:重写方法的方法的具体内容。

  • 具体格式

       1、无参,无返回值

                

      2、有一个参数、无返回值

               

      3、多个参数、有返回值

              

      4、总结

           ->左边:

             (1)因为可以进行类型推断,所以可以不用写形参的类型;

             (2)如果只有一个参数,()可以不写。

          ->右边:

            (1){}将方法体的具体内容包裹起来;

            (2)方法体只有一条语句,{}可以不写;

            (3)如果方法体只有一条并且这条语句就是返回语句,return关键字可以不写。

二、函数是接口

Lambda表达式是接口的实现类的对象,因此Lambda需要依赖一个接口,那么这个接口有什么要求吗?

Lambda所依赖的接口的要求:要求这个接口必须只有一个抽象方法。

  • 函数是接口:(1)只有一个抽象方法;(2)jdk8以后可以有非抽象方法。
  • 自定义函数式接口

在自定义函数式接口前面加上一个注解:@FunctionalInterface,如果检测到多个抽象方法是会报错

 

  • 四个常用的内置函数式接口

有一些接口系统已经为我们提供好,没有必要自己再去写。

java8中的java.util.function包下:

  1. 消费型接口:Consumer  —>  void accept(T t)  传入参数,没有返回值类型;
  2. 断定型接口:Predicate   —>   boolean test(T t) 传入T,返回布尔类型;
  3. 函数型接口:Function    —>   R apply(T t) 传入T,得到R;
  4. 供给型接口:Supplier     —>  T get() 不用传入参数,有返回值
  • 内置函数式接口举例
  • 消费型接口:Consumer  —>  void accept(T t)  传入参数,没有返回值类型;
    import java.util.function.Consumer;
    
    //2、使用内置的Consumer接口
    class Demo1{
        public static void main(String[] args) {
            Consumer<Double> sm  = money -> System.out.println("花了"+money+"块钱买书");
            buySomething(100,sm);
        }
        public static void buySomething(double money,Consumer sm){
            sm.accept(money);
        }
    }
  • 断定型接口:Predicate   —>   boolean test(T t) 传入T,返回布尔类型;

       需求:从给定的字符串集合中挑选出长度大于5的字符串。

      (1)未使用Lambda表达式代码

/**
 * 从给定的字符串集合中挑选出长度大于5的字符串。
 */
public class PredicateInterfaceTest {
    public static void main(String[] args) {
        List<String> strs = Arrays.asList("faefwaef", "dew", "fwe21a", "dfwa", "as", "1fafa");
        List<String> newStrs = getFilterString(strs, new Predicate<String>() {
            @Override
            public boolean test(String str) {
                return str.length()>5;
            }
        });
        for (String newStr : newStrs) {
            System.out.println(newStr);
        }
    }
    //返回字符串长度大于5的字符串集合
    public static List<String> getFilterString(List<String> strs, Predicate<String> sp){
         //思路:把符合条件的字符串放到一个新的集合,然后返回
        ArrayList<String> newStrs = new ArrayList<>();
        for (String str : strs) {
            if (sp.test(str)) {
                newStrs.add(str);
            }
        }
        return newStrs;
    }
}

       (2)使用Lambda表达式后的代码

/**
 * 从给定的字符串集合中挑选出长度大于5的字符串。
 */
public class PredicateInterfaceTest {
    public static void main(String[] args) {
        List<String> strs = Arrays.asList("faefwaef", "dew", "fwe21a", "dfwa", "as", "1fafa");
        List<String> newStrs = getFilterString(strs, (str)->str.length()>5);
        for (String newStr : newStrs) {
            System.out.println(newStr);
        }
    }
    //返回字符串长度大于5的字符串集合
    public static List<String> getFilterString(List<String> strs, Predicate<String> sp){
         //思路:把符合条件的字符串放到一个新的集合,然后返回
        ArrayList<String> newStrs = new ArrayList<>();
        for (String str : strs) {
            if (sp.test(str)) {
                newStrs.add(str);
            }
        }
        return newStrs;
    }
}
发布了28 篇原创文章 · 获赞 5 · 访问量 1173

猜你喜欢

转载自blog.csdn.net/weixin_40391011/article/details/104031152