Lambda表达式和函数式接口

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/iuie_sl/article/details/55504354

Lambda表达式产生的原因

Java是一门面向对象的语言,面向对象的语言使用带有方法的对象封装行为,而函数式编程使用函数封装行为,Java的对象一般比较重量级。当实例化一个对象时往往涉及到初始化他用到的其他字段和方法以及类。为了对那些只在调用处使用一次的方法提供一种轻量级的封装,Java的Lambda出生了。在没有Lambda表达式的时候我们一般使用匿名内部类来处理这种需求,但是匿名内部类有以下不足
1. 语法不简洁
2. 匿名内部类的this和变量名容易让人产生误解
3. 类载入和实例创建语句不够灵活
4. 无法获取非final的局部变量
5. 无法对控制流进行抽象

函数式接口

我们把只有一个方法的接口叫做函数式接口。函数式接口不需要加任何额外的东西,编译器会自动判断(判断过程并非简单的对接口方法计数:一个接口可能冗余的定义了一个Object已经提供的方法,比如toString(),或者定义了静态方法或默认方法,这些都不属于函数式接口方法的范畴)。也可以通过@FunctionalInterface注解来显式指定一个接口是函数式接口。我们现在的类库有很多是函数式接口的,就可以直接使用lamdba表达式。
- Java8增加了一个新包,java.util.function,它里面包含了常用的函数式接口
1. Predicate——接收T对象并返回boolean
2. Consumer——接收T对象,不返回值
3. Supplier——提供T对象(例如工厂),不接收值
4. UnaryOperator——接收T对象,返回T对象
5. BinaryOperator——接收两个T对象,返回T对象

public static void hasDoneLambda(){
       // Function<T, R> -T作为输入,返回的R作为输出
       Function<String,String> function=(x)->{
           return "function"+x;
       };
       System.out.println(function.apply("舒莉"));

      //Predicate<T> -T作为输入,返回的boolean值作为输出
       Predicate<String> predicate=(s)->{
           System.out.println(s);
           return false;
       };
       predicate.test("hello world");

      //Consumer<T> - T作为输入,执行某种动作但没有返回值
       Consumer<String>  consumer=(s)->{
           System.out.println(s);
       };
       consumer.accept("shuli");


       //Supplier<T> - 没有任何输入,返回T
       Supplier<String> supp = () -> {return "Supplier";};
       System.out.println(supp.get());

       //BinaryOperator<T> -两个T作为输入,返回一个T作为输出,对于“reduce”操作很有用
       BinaryOperator<String> bina = (x,y) ->{System.out.print(x+" "+y);return "BinaryOperator";};

       System.out.println("  "+bina.apply("hello ","world"));
   }  

自定义函数式接口

package lambda;

@FunctionalInterface
public interface StringConvertInteger<S,T> {

    T convert(S s);
} 

函数式接口转Lambda表达式

public static void main(String[] args) {
      //用函数块实现方法
        StringConvertInteger<String,Integer> stringConvertInteger=(s)->{
                Integer result=Integer.valueOf(s);
                System.out.println(result);
                return result;
              };
        //调用
        stringConvertInteger.convert("123");
    }

注:

  • 泛型类型是必须指定的,编译器根据他们推断出方法的传入参数类型和返回值类型。
  • 函数块类可以调用类的成员变量和局部变量,编译器会自动把类的成员变量和局部变量转成final类型的,如果类的成员变量和局部变量值发生了变化,编译器无法推断他是final类型的调用就会出错。

总结

Lambda表达式主要由4部分组成
1. 函数式接口
2. 参数列表
3. 符号->
4. 函数体。

引用:http://www.cnblogs.com/figure9/archive/2014/10/24/4048421.html

猜你喜欢

转载自blog.csdn.net/iuie_sl/article/details/55504354