JAVA8新特性——深入浅出了解Lambda表达式(基础篇)

Lambda表达式基础

​ lambda表达式是JDK8中的新特性,其实这个功能并非不可或缺的,只是它可以起到简化代码,锻炼思维的作用。现在很多教程中对lambda表达式介绍过于简单或是结合了高级特性,让很多第一次接触lambda表达式的程序员有些迷茫,在这篇文章中我会尽力用简练的语言,详细的代码分析,让各位了解到lambda表达式的有趣之处。

基础知识

匿名内部类

​ 匿名内部类就是没有名字的内部类

​ 因为没有名字,所以每个匿名内部类只能使用一次

必须继承一个父类或者实现一个接口

匿名内部类不能定义任何静态成员、方法。

匿名内部类中的方法不能是抽象的;

匿名内部类必须实现接口或抽象父类的所有抽象方法。

匿名内部类访问的外部类成员变量或成员方法必须用static修饰;

interface Printer{
		void printstring(String str);
	}
//以下为通过匿名内部类接口的实现
Printer aPrinter = new Printer() {
			
			@Override
			public void printstring(String str) {
				// TODO 自动生成的方法存根
				System.out.println(s1);
			}
		};

Lambda表达式

简介

Lambda表达式是 JDK8 新特性,使用它可以取代绝大多数的匿名内部类,使得代码更加简洁。

对接口的要求

Lambda 规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法。

基础语法

interface Printer{
		void printstring(String str);
	}
Printer bPrinter = (str)->{System.out.println(str);};

我们可以看到,相比于上面使用匿名内部类的直接实现,使用lambda表达式可以极大地减少代码长度。

函数式接口

  • 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。

  • 函数式接口可以被隐式转换为 lambda 表达式。

  • JDK提供了部分函数式接口

  • 我们可以使用JDK提供的函数式接口完成lambda表达式以减少我们的工作量。

在JDK8之后,添加了一个包java.util.function。它包含了很多类,用来支持Java的函数式编程。例如:Predicate,使用其函数式接口以及lambda表达式,可以向API方法添加逻辑,用更少的代码支持更多的动态行为。

–Consumer代表了接受一个输入参数并且无返回的操作

–Predicate接受一个输入参数,返回一个布尔值结果。

–Supplier无参数,返回一个结果。

–Function<T,R>接受一个输入参数,返回一个结果。

–BinaryOperator代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果

以下是有两个传入参数的函数式接口

•BiConsumer<T,U>代表了一个接受两个输入参数的操作,并且不返回任何结果

•BiFunction<T,U,R>代表了一个接受两个输入参数的方法,并且返回一个结果

•BiPredicate<T,U>代表了一个两个参数的boolean值方法

在之后的示例中,我们将会演示如何通过提供的函数式接口运用lambda表达式。

使用lambda表达式完成数组迭代

//forEach的接受传参为Consumer,即传入一个参数,无返回值
//以下为函数原型
//public void forEach(Consumer<? super E> action)
List<String> langStrings = Arrays.asList("C++","JAVA","C#","Python");
langStrings.forEach(n->System.out.println(n));

在本例中我们使用lambda表达式实现了数组的全元素迭代。输出了数组中的全部元素。

下一个例子与此相比会有一些复杂,但我会尝试通过详细的说明,帮助各位理解它。

class pickStrings{
    //定义静态方法filter,传参是一个字符串列表以及Predicate
	public static void filter(List<String>lans,Predicate<String> conditon){
		for (String lan : lans) {
            //见说明2
			if (conditon.test(lan)) {
				System.out.println(lan);
			}
		}
	}
}

public class lambdatest {
	public static void main(String[] args) {
		List<String> langStrings = Arrays.asList("C++","JAVA","C#","Python",
				"PHP","C");
        //使用String下方法startwith作为传入参数,过滤列表中字符串
		pickStrings.filter(langStrings, str->str.startsWith("C"));
	}

}

这个代码块的作用是输出List中所有以“C”开头的元素,即使没有lambda表达式,我们通过迭代也可以完成相应的功能,但是通过这个新特性,我们可以通过简单的代码完成复杂的工作。我将在下面对上方代码进行详细说明

  1. 静态方法filter接受两个参数,前面我们已经给出,*Predicate()*是接受一个参数,返回一个boolean结果的函数式接口,因此我们采用它作为字符串筛选的“过滤器”。

  2. test()方法是Predicate接口中的一个布尔型函数,其作用简单地说就是判别括号内的元素是否满足条件(在本例中判断是否满足传入对象condition的条件)。

至此各位应该都对lambda表达式有了一定了理解,在之后的文章中我还会介绍StreamAPI,以及Stream与lambda结合以期达成更高效的数据处理,欢迎各位持续关注。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值