函数式编程与lamada表达式

函数式编程与lamada表达式

  • 函数式接口
  • lamada表达式

函数式接口

在谈lamada表达式之前,有必要先了解下什么是函数式接口。为了支持函数式编程,JDK8 新增了一个函数式接口FunctionalInterface。官网上有对该接口详细介绍。如下
函数式编程与lamada表达式_第1张图片
图1 FunctionalInterface介绍图

主要说的是,函数式接口只能有一个抽象方法,注意,声明为default不算在其中,或者Object里的public方法,即使被继承并改为abstract,也不算在其中,因为它们都是在自身或某个地方有实现的。

@FunctionalInterface
public interface testi<T> {
     	
	@SuppressWarnings("hiding")
	<T> void abstractMethod(T t);
		
	int hashCode();
}

在上面的方法中,虽然有两个抽象方法,但是,由于hashCode属于Object的public方法,因此,只算abstractMethod一个,所以testi接口会被当做一个函数式接口。
函数式编程与lamada表达式_第2张图片
图2 符合定义的函数式接口不会弹错误提示

如果我们将hashCode改成hashCode1,由于加了FunctionalInterface注解,因此会在编译时就发现这个错误,并弹出提示。testi接口不是一个函数式接口
函数式编程与lamada表达式_第3张图片
图3 不符合定义的函数式接口弹错误提示

对于符合函数式接口定义的接口,加不加FunctionalInterface注解都可以,但是加了之后,会在编译时就提前检查,能提前发现错误,因此官网时推荐添加该注解的。

那么为什么要提供这个函数式接口呢?理由是函数接口的实例可以用lambda表达式、方法引用或构造函数引用创建

lamada表达式

在介绍lamada表达式之前,需要先介绍下匿名内部类,因为lamada表达式通常被用作简化创建匿名内部类。

public class CollectionTest {
     
	@FunctionalInterface
	public interface testi<T> {
     
		@SuppressWarnings("hiding")
		<T> void abstractMethod(T t);
		int hashCode();
	}

    public static void main(String[] args) throws IOException {
     
       Integer[] integers=new Integer[] {
     1,3,4,5,5,67,8,8,6};
       //传统方式,匿名内部类
       for(Integer i:integers) {
     
    	   new testi<Object>() {
     
    		   @Override
    		   public void abstractMethod(Object t) {
     
    			   System.out.println(t);
    		   }
    	   }.abstractMethod(i);
       } 
    } 
}

如上所示

new testi<Object>() {
     
	@Override
   	public void abstractMethod(Object t) {
     
    	System.out.println(t);
    }
}.abstractMethod(i);

该匿名内部类的意思是,创建一个实例,并重写父类抽象方法,并在创建完成后调用该方法,结果如下。
函数式编程与lamada表达式_第4张图片
图4 传统匿名内部类输出

将其改为lamada表达式后,代码如下

public class CollectionTest {
     
	@FunctionalInterface
	public interface testi<T> {
     
		@SuppressWarnings("hiding")
		<T> void abstractMethod(T t);
		int hashCode();
	}

    public static void main(String[] args) throws IOException {
     
       fun((x) -> System.out.println("Hello World " + x)); 
    } 
    @SuppressWarnings({
      "unchecked", "rawtypes" })
	static void fun(testi t) {
     
    	Integer[] integers=new Integer[] {
     1,3,4,5,5,67,8,8,6};
    	for(Integer i:integers)
    		t.abstractMethod(i);
    } 
}

在上述代码中

(x) -> System.out.println("Hello World " + x)

本质是创建一个匿名内部类,其中右边部分为重写方法

System.out.println("Hello World " + x)

而左边是传入的参数,也就是在方法体中能被使用到,结果如下。
函数式编程与lamada表达式_第5张图片
图5 lamada表达式输出

关于更多的lamada表达式,请参考 JDK8的新特性——Lambda表达式
但是注意,这篇博客有个解释得不怎么好的地方
在这里插入图片描述
图6 该博客解释不准确的点

详情请参考上述的官方解释
关于lamada表达式的更多用法,请参考 Lambda表达式更多用法

你可能感兴趣的:(lambda,java)