Java Lambda表达式与函数式接口

Lambda表达式

1.什么是Lambda表达式:

简洁的表示可以传递的匿名函数的一种方式。

没有名称,但是有参数列表,函数主体,返回类型。

2.Lambda表达式的特性:

  1. 匿名:和普通方法不一样,没有一个明确的名字;
  2. 函数:Lambda表达式不属于任何一个类;
  3. 传递:Lambda表达式可以作为参数(传递给方法,赋值给变量);
  4. 简洁:不需要像内部类那样,需要写很多的模板代码。

3.Lambda表达式由三部分构成:

  1. 参数列表;
  2. 箭头:参数列表和后面的代码块的连接符;
  3. Lambda的主体。

4.Lambda表达式的两种写法:

  1. (参数列表)-> 代码 (默认会有一个return ,代码段的结尾不需要写分号)
  2. (参数列表)-> {代码段;}(代码段的结尾需要写分号)

参数的类型既可以明确声明,也可以根据上下文来推断: (int a)(a)

当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a

总结:4个特性,3个部分,2种写法

Lambda表达式案例:

  1. (String s)-> s.length()
  2. (Apple a) -> a.getWeight() > 150
  3. (int x , int y) -> { System.out.println("");}
  4. ()->42
  5. () -> "helloworld"

测验:下面哪些不是lambda表达式

	(1) 
			()->{}  
	 (2)
			() -> "haha"
	 (3)
			() ->{return "haha";}
	 (4)
			(Integer i) -> return i ;  
	 (5)
			(String s) -> { s }

答案:(4)(5), (1)是:Runnable()接口中的 void run()

函数式接口:

1.在哪里可以用lambda表达式呢?

在有函数式接口的地方可以使用lambda

2.什么是函数式接口?

大多数的场景下,只有一个抽象方法的接口是函数式接口

//Supplier就是一个函数式接口
public interface Supplier<T> {
    T get();
} 
//自定义了一个方法,参数是个接口
public static void f3(Supplier<String> supplier){
    System.out.println(supplier.get());
}

使用匿名内部类实例化函数式接口的对象:

f3(new Supplier<String>() {
	
	@Override
	public String get() {
		
		return "helloworld";
	}
});     //模板代码多,有用的就一句return

采用lambda表达式:

f3(
    ()->"helloworld"      //String get()
);

测验:下面哪些不是函数式接口?

(1)
	public interface Adder{
		int add(int a ,int b);
	}
(2)
	public interface sAdder extends Adder{
		int add(double a ,double b);
	}
(3)
	public interface Nothing{}

答案:(2)(3) (2里有两个方法,没有重写)

lambda与函数式接口:

@Test
public void test4(){

    //lambda表达式  可以看成一个实现了run方法的一个实例对象
    Runnable r2 = () -> System.out.println("hellowrold - r2");

    //匿名内部类 实例对象
    Runnable r1 = new Runnable() {
        @Override
        public void run() {
            System.out.println("hello world");
        }
    };
    // public Thread(Runnable target)  //函数式接口
    // public abstract void run();   // 参数类型
    new Thread(r1).start();
    new Thread(r2).start();
}

@FunctionalInterface注解:声明一个接口是一个函数式接口

记忆:加注解的接口里只能有一个“有效”的抽象方法

网上有很多关于函数式接口的解释严格意义上都不正确,这里纠正下:

函数式接口里面可以有多个抽象方法:编译检查的时候Object抽象方法不会做考虑的。

//有多个抽象方法的函数式接口,下面这个是可以的
@FunctionalInterface
public interface BufferedReaderProcessor{
    String process(BufferedReader br);
    int hashCode();
    boolean equals(Object var1);
}
//用lambda表达式实例化对象
public void test1() {
    /**
     * 受检异常
     * 1.throws
     * 2.try catch
     */
    BufferedReaderProcessor brf = (BufferedReader br)->br.readLine(); //需要抛出个异常,需要在接口中定义的方法后面抛出
}
@FunctionalInterface
public interface BufferedReaderProcessor{
    String process(BufferedReader br) throws IOException;
    int hashCode();
    boolean equals(Object var1);
}

猜你喜欢

转载自www.cnblogs.com/yZzcXQ/p/Lambda-FunctionInterface.html