CoreJava读书笔记--接口、lambda表达式、内部类(三)--lambda表达式

lambda表达式

(一)为什么要引入lambda表达式?

lambda表达式是一个匿名函数,可以把lambda表达式理解成一段可以像数据一样传递的代码块。目的是更简洁,更灵活。

lambda表达式可以用更简洁的方式来创建只有一个抽象方法的接口(函数式接口)的实例。

我们可以先来看看下面的代码:

Comparator<String> comp = new Comparator<String>() {
		@Override
		public int compare(String s1,String s2) {
			return Integer.compare(s1.length(), s2.length());
		}
	};

 上面的代码中,就是一个匿名内部类的方式创建Comparator对象comp,执行的代码也仅仅是Integer.compare(s1.length(),s2.length());这一段,那么我们使用lambda表达式的形式来看:

Comparator<String> comp = (x,y)->Integer.compare(x.length(),y.length());

从上面可以看出,lambda表达式更简洁,更灵活。

(二)lambda表达式的语法

lambda表达式形式:参数,箭头(->),以及一个表达式或代码块

基本语法

(parameters) -> expression

(parameters) ->{ statements; }

格式一:无参数,无返回值

()->System.out.println("Hello,World");

格式二:有一个参数,无返回值

(x)->System.out.println(x);

格式三:若只有一个参数,小括号可以不写

x->System.out.println(x);

格式四:有两个以上参数,有返回值,并且lambda体中有多条语句

Comparator<Integer> comp = (x,y)->{
    System.out.println("函数式接口");
    return Integer.compare(x,y);
};

格式五:若lambda里只有一条语句,大括号和return都不需要写

Comparator<Integer> comp = (x,y)->Integer.compare(x,y);

格式六:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”

(Integer x, Integer y) -> Integer.compare(x, y);

接下来看看之前写过的比较器,用lambda表达式来实现:

package lambda;

import java.util.Arrays;
import java.util.Comparator;

public class LambdaTest {
	public static void main(String[] args) {
		String[] s = {"abcde","bcde","a","cde","ab"};
		Comparator<String> comp = (x,y)->Integer.compare(x.length(), y.length());
		Arrays.sort(s, comp);
		for(String e : s) {
			System.out.println(e);
		}
	}
}

 (三)函数式接口

什么是函数式接口?

对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口就称为函数式接口。

注意:在Java8中,默认方法和静态方法都不是抽象方法;并且接口继承Object,如果接口声明了Object类的方法,也不算是抽象方法。

函数式接口有一个注解@FunctionalInterface,这个注解只能标记在有且只有一个的接口上。当然并不是函数式接口就必须要用它标记,也可以不进行标记。如果你所写的不是函数式接口,用了这个标记,编译器就会报错。

package lambda;
@FunctionalInterface
public interface FunctionalInterfaceTest {
	//抽象方法,有且只有一个
	int sub();
	//默认方法,可以有
	default int multiply(int x,int y) {
		return x*y;
	}
	//Object类的方法
	public boolean equals(Object obj);
	
	//Java8中可以声明静态方法
	public static void add() {
		System.out.println("Hello");
	}
}

(四)方法引用

有时,可能已经有现成的方法可以完成你想要传递到其他代码的某个动作。这时可以使用方法引用。

方法的引用有三种形式:

①Class::staticMethod  ;②object::instanceMethod;③Class::instanceMethod。

种类 示例 说明 对应的lambda表达式
引用类方法 类名::类方法 函数式接口中被实现方法的全部参数传给该类方法作为参数 (a,b,...)->类名.类方法(a,b,...)
引用特定对象的实例方法 特定对象::实例方法 函数式接口中被实现方法的全部参数传给该方法作为参数 (a,b,...)->特定对象.实例方法(a,b,...)
引用某类对象的实例方法 类名::实例方法 函数式接口中被实现方法的第一个参数作为调用者,后面的参数全部传给该方法作为参数 (a,b,...)->a.实例方法(b,...)
引用构造器 类名::new 函数式接口中被实现方法的全部参数传给该构造器作为参数 (a,b,...)->new 类名(a,b,...)

 1.引用类方法 例如:Math::pow等价于(x,y)->Math.pow(x,y);

 2.引用特定对象的实例方法  例如: System.out::println等价于(x)->System.out.println(x);

 3.引用某类对象的实例方法  例如: String::compareToIgnoreCase等价于(x,y)->x.compareToIgnoreCase(y);

同样的,this和super也可以使用方法。例如:this::equals等等。

(五)构造器引用

构造器引用和方法引用类似,方法名变成了new关键字。我们看看代码:

package lambda;

import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

public class ConstructorTest {
	public static void main(String[] args) {
		//下面是传统的lambda表达式和构造器引用的比较
		//传统lambda表达式
		Supplier<Employee> sup = ()->new Employee();
		//①无参构造器
		Supplier<Employee> sup2 = Employee::new;
		//②一个参数的构造器
		Function<String,Employee> fun = Employee::new;
		System.out.println(fun.apply("a"));
		//③两个参数的构造器
		BiFunction<String,Integer,Employee> bi = Employee::new;
		System.out.println(bi.apply("b", 20));
	}
}

class Employee{
	private String name;
	private int id;
	private int age;
	private double salary;
	
	public Employee() {
		
	}
	
	public Employee(String name) {
		this.name=name;
	}
	
	public Employee(String name,int age) {
		this.name=name;
		this.age=age;
	}
	
	public Employee(String name,int age,int id,double salary) {
		this.name=name;
		this.age=age;
		this.id=id;
		this.salary=salary;
	}
	
	public String toString() {
		return getClass().getName()+"[name="+name+",age="+age+
				",id="+id+",salary="+salary+"]";
	}
}

 lambda表达式还有很多类型,接下来在熟悉内部类,集合批处理等操作后,再来看看lambda表达式还有哪些用法。

猜你喜欢

转载自blog.csdn.net/zxyy2627/article/details/82664240