Java基础学习第二十三讲:Lambda表达式

Lambda表达式

一、Lambda表达式背景

Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。

二、Lambda表达式基本语法

()->{}

Java基础学习第二十三讲:Lambda表达式_第1张图片
Lambda表达式由三部分组成:

  • 参数:类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明,也可不声明而由JVM隐含的推断。另外当只有一个参数时可以省略掉圆括号。
  • ->:可理解为“应用于”的意思
  • 方法体:可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不反 回,这里的代码块块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不反回。

三、Lambda函数式接口

要想了解什么是Lambda表达式,首先要了解什么是函数式接口。所谓函数式接口:
首先:接口中只能有一个抽象方法,那么这个接口就是函数式接口
其次:可以在接口中使用@FunctionalInterface注解,使编译器按照函数是接口进行要求,如果在接口中存在多个抽象方法,编译器就会提示。
第三:如果你可以保证你的接口中确实只有一个方法,那么编译器就会默认为函数式接口,不会因@FunctionalInterface注解而定。

@FunctionalInterface
public interface IFuncationInterface {
	//注意:只能有一个方法存在,如果不加入@FunctionalInterface,编译器会根据情况而定
	public void say();
}
public static void main(String[] args) {
	//声明接口对象,通过Lambda表达式实现方法
	IFuncationInterface funcationInterface=()->{System.out.println("大家好,我是Lambda表达式");};
	//调用接口方法
	funcationInterface.say();
}

Java基础学习第二十三讲:Lambda表达式_第2张图片

四、Lambda表达式使用

//无参数无返回值的方法
@FunctionalInterface
public interface IOneInterface {
	public void say();
}
//无参数有返回值的方法
public interface ITwoInterface{
	public String say();
}
//有参数有返回值的方法
public interface IThreeInterface {
	public String say(String name,int age);
}

public static void main(String[] args) {
		
	//无参数无返回值方法
	IOneInterface oneInterface=()->System.out.println("我是无返回值无参数方法");
	oneInterface.say();
		
	//无参数有返回值方法
	ITwoInterface twoInterface=()->"我是有返回值无参数方法,我只有一句话,所以我省略return";
	String str=twoInterface.say();
	System.out.println(str);
		
	//有参数有返回值方法
	IThreeInterface threeInterface=(name,age)->name+"今年"+age+"岁了,所以我是一个有参数有返回值的方法";
	String s=threeInterface.say("张三",18);
	System.out.println(s);
	}

Java基础学习第二十三讲:Lambda表达式_第3张图片使用Lambda时,要记住的就两点:

  • Lambda返回的是接口的实例对象
  • 有没有参数、参数有多少个、需不需要有返回值、返回值的类型是什么---->选择自己合适的函数式接口

五、Lambda表达式特点

  • 参数类型可以省略,如果需要省略,每个参数的类型都要省略。

  • 参数的小括号里面只有一个参数,那么小括号可以省略。

  • 如果方法体当中只有一句代码,那么大括号可以省略。

  • 如果方法体中只有一条语句,其是return语句,那么大括号可以省略,且去掉return关键字。

    优点:
    代码简洁,开发迅速
    方便函数式编程
    非常容易进行并行计算
    Java 引入 Lambda,改善了集合操作
    缺点:
    代码可读性变差
    在非并行计算中,很多计算未必有传统的 for 性能要高
    不容易进行调试

总结:Lambda表达式能够帮助我们快速完成代码,使代码更简洁,更直观的去实现内容,同时也为我们阅读代码增加了一定的难度

六、Lambda表达式集合中的应用

  • 实现List集合循环
List<String> strList=new ArrayList<String>();
strList.add("Hello");
strList.add("World");
strList.add("Hello");
strList.add("Java");
strList.add("World");
		
strList.forEach(str->System.out.println(str));
  • 实现Set集合循环
Set<String> strList=new HashSet<String>();
strList.add("Hello");
strList.add("World");
strList.add("Hello");
strList.add("Java");
strList.add("World");
		
strList.forEach(str->System.out.println(str));
  • 实现Map集合循环
Map<Integer,String> strList=new HashMap<Integer,String>();
strList.put(1,"Hello");
strList.put(2,"World");
strList.put(3,"Hello");
strList.put(4,"Java");
strList.put(5,"World");
		
strList.forEach((i,s)->System.out.println(i+"---"+s));

七、方法引用

在使用Lambda表达式时,我们有时会遇到这样的写法

List<String> strList=new ArrayList<String>();
strList.add("Hello");
strList.add("World");
strList.add("Hello");
strList.add("Java");
strList.add("World");
		
strList.forEach(str->System.out.println(str));
//这样写也可以实现?
strList.forEach(System.out::println);

答案是肯定的,这样写确实可以实现,这种形式,是Lambda表达式中更简洁的写法,方法的引用。

如果函数式接口的实现恰好可以通过调用一个方法来实现,那么我们可以使用方法引用

方法的引用包含

  • 引用普通方法
  • 引用静态方法
  • 引用构造方法
public class ImplementInterface{
	public static void say(String name) {
		System.out.println(name);
	}
	
	public void say1(String name) {
		System.out.println(name);
	}

	public ImplementInterface() {
		System.out.println("我是构造方法");
	}
}
public static void main(String[] args) {
		
	//通过类调用静态方法
	Consumer<String> consumer=ImplementInterface::say;
	consumer.accept("我是静态方法");

	//通过对象调用普通方法
	ImplementInterface implementInterface=new ImplementInterface();
	Consumer<String> consumer2=implementInterface::say1;
	consumer2.accept("我是普通方法");
		
	//通过类调用构造方法
	Supplier<ImplementInterface> supplier=ImplementInterface::new;
	System.out.println(supplier.get());
}

你可能感兴趣的:(Java基础学习,java,学习,jvm)