这个「Java 8新特性:lambda表达式」百家号小程序的功能能满足我使用它的基本诉求,可以可以
分类:新闻资讯
开发作者:
发布时间:
更新时间:
「Java 8新特性:lambda表达式」百家号_作者自评:
如何看待百家号Lite小程序热议话题「Java 8新特性:lambda表达式」
转载自百家号作者:BaiduSpringlambda表达式是java8th给我们带来的几个重量级新特性之一,借用lambda表达式可以让我们的程序设计更加简洁。一.行为参数化行为参数化简单的说就是将方法的逻辑以参数的形式传递到方法中,方法主体仅包含模板类通用代码,而一些会随着业务场景而变化的逻辑则以参数的形式传递到方法之中,采用行为参数化可以让程序更加的通用,以应对频繁变更的需求。这里我们以java8inaction中的例子进行说明。考虑一个业务场景,假设我们需要通过程序对苹果按照一定的条件进行筛选,我们先定义一个苹果实体:用户最开始的需求可能只是简单的希望能够通过程序筛选出绿色的苹果,于是我们可以很快的通过程序实现:如果过了一段时间用户提出了新的需求,希望能够通过程序筛选出红色的苹果,于是我们又需要针对性的添加了筛选红色苹果的功能:更通用的实现是把颜色作为一个参数传递到方法中,这样就可以应对以后用户提出的各种颜色筛选需求:这样的设计再也不用担心用户的颜色筛选需求变化了,但是不幸的是某一天用户提了一个需求希望能够筛选重量达到某一标准的苹果,有了前面的教训我们也把重量的标准作为参数传递给筛选函数:这样通过传递参数的方式真的好吗?如果筛选条件越来越多,组合模式越来越复杂,我们是不是需要考虑到所有的情况,并针对每一种情况都实现相应的策略呢?并且这些函数仅仅是筛选条件的部分不一样,其余部分都是相同的模板代码(遍历集合),这个时候我们就可以将行为进行参数化处理,让函数仅保留模板代码,而把筛选条件抽离出来当做参数传递进来,在java8th之前,我们通过定义一个过滤器接口来实现:通过上面行为抽象化之后,我们可以在具体调用的地方设置筛选条件,并将条件作为参数传递到方法中:上面的行为参数化方式采用匿名类实现,这样的设计在jdk内部也经常采用,比如java.util.Comparator,java.util.concurrent.Callable等,使用这类接口的时候,我们都可以在具体调用的地方用匿名类指定函数的具体执行逻辑,不过从上面的代码块来看,虽然很极客,但是不够简洁,在java8th中我们可以通过lambda表达式进行简化:如上述所示,通过lambda表达式极大精简了代码,同时行为参数让我们的程序极大的增强了可扩展性。二.Lambda表达式2.1Lambda表达式的定义与形式我们可以将lambda表达式定义为一种简洁、可传递的匿名函数,首先我们需要明确lambda表达式本质上是一个函数,虽然它不属于某个特定的类,但具备参数列表、函数主体、返回类型,甚至能够抛出异常;其次它是匿名的,lambda表达式没有具体的函数名称;lambda表达式可以像参数一样进行传递,从而简化代码的编写,其格式定义如下:参数列表->表达式参数列表->{表达式集合}需要注意lambda表达式隐含了return关键字,所以在单个的表达式中,我们无需显式的写return关键字,但是当表达式是一个语句集合的时候则需要显式添加return关键字,并用花括号{}将多个表达式包围起来,下面看几个例子:2.2基于函数式接口使用lambda表达式lambda表达式的使用需要借助于函数式接口,也就是说只有函数式接口出现地方,我们才可以将其用lambda表达式进行简化。那么什么是函数接口?函数接口的定义如下:函数式接口定义为仅含有一个抽象方法的接口。按照这个定义,我们可以确定一个接口如果声明了两个或两个以上的方法就不叫函数式接口,需要注意一点的是java8th为接口的定义引入了默认的方法,我们可以用default关键字在接口中定义具备方法体的方法,这个在后面的文章中专门讲解,如果一个接口存在多个默认方法,但是仍然仅含有一个抽象方法,那么这个接口也符合函数式接口的定义。2.2.1自定义函数式接口我们在前面例子中实现的苹果筛选接口就是一个函数式接口(定义如下),正因为如此我们可以将筛选逻辑参数化,并应用lambda表达式:AppleFilter仅包含一个抽象方法accept(Appleapple),依照定义可以将其视为一个函数式接口。在定义时我们为该接口添加了@FunctionalInterface注解,用于标记该接口是一个函数式接口,不过该注解是可选的,当添加了该注解之后,编译器会限制了该接口只允许有一个抽象方法,否则报错,所以推荐为函数式接口添加该注解。2.2.2jdk自带的函数式接口jdk为lambda表达式已经内置了丰富的函数式接口,如下表所示(仅列出部分):其中最典型的三个接口是Predicate<T>、Consumer<T>,以及Function<T,R>,其余接口几乎都是对这三个接口的定制化,下面就这三个接口举例说明其用处,针对接口中提供的逻辑操作默认方法,留到后面介绍接口的default方法时再进行说明。Predicate<T>Predicate的功能类似于上面的AppleFilter,利用我们在外部设定的条件对于传入的参数进行校验并返回验证通过与否,下面利用Predicate对List集合的元素进行过滤:上述方法的逻辑是遍历集合中的元素,通过Predicate对集合元素进行验证,并将验证不过的元素从集合中移除。我们可以利用上面的函数式接口筛选整数集合中的偶数:Consumer<T>Consumer提供了一个accept抽象函数,该函数接收参数并依据传递的行为应用传递的参数值,下面利用Consumer遍历字符串集合并转换成小写进行打印:利用上面的函数式接口,遍历字符串集合并以小写形式打印输出:Function<T,R>Funcation执行转换操作,输入类型T的数据,返回R类型的结果,下面利用Function对字符串集合转换成整型集合,并忽略掉不是数值型的字符:下面利用上面的函数式接口,将一个封装字符串的集合转换成整型集合,忽略不是数值形式的字符串:2.2.3一些需要注意的事情类型推断在编码过程中,有时候可能会疑惑我们的调用代码会具体匹配哪个函数式接口,实际上编译器会根据参数、返回类型、异常类型(如果存在)等因素做正确的判定。在具体调用时,一些时候可以省略参数的类型以进一步简化代码:局部变量上面所有例子中使用的变量都是lambda表达式的主体参数,我们也可以在lambda中使用实例变量、静态变量,以及局部变量,如下代码为在lambda表达式中使用局部变量:上述示例我们在lambda中使用了局部变量weight,不过在lambda中使用局部变量还是有很多限制,学习初期IDE可能经常会提示我们Variableusedinlambdaexpressionshouldbefinaloreffectivelyfinal的错误,即要求在lambda表达式中使用的变量必须显式声明为final或事实上的final类型。为什么要限制我们直接使用外部的局部变量呢?主要原因在于内存模型,我们都知道实例变量在堆上分配的,而局部变量在栈上进行分配,lambda表达式运行在一个独立的线程中,了解JVM的同学应该都知道栈内存是线程私有的,所以局部变量也属于线程私有,如果肆意的允许lambda表达式引用局部变量,可能会存在局部变量以及所属的线程被回收,而lambda表达式所在的线程却无从知晓,这个时候去访问就会出现错误,之所以允许引用事实上的final(没有被声明为final,但是实际中不存在更改变量值的逻辑),是因为对于该变量操作的是变量副本,因为变量值不会被更改,所以这份副本始终有效。这一限制可能会让刚刚开始接触函数式编程的同学不太适应,需要慢慢的转变思维方式。实际上在java8th之前,我们在方法中使用内部类时就已经遇到了这样的限制,因为生命周期的限制JVM采用复制的策略将局部变量复制一份到内部类中,但是这样会带来多个线程中数据不一致的问题,于是衍生了禁止修改内部类引用的外部局部变量这一简单、粗暴的策略,只不过在8th之前必须要求这部分变量采用final修饰,但是8th开始放宽了这一限制,只要求所引用变量是“事实上”的final类型即可。三.方法引用方法引用可以更近一步的简化代码,有时候这种简化让代码看上去更加直观,先看一个例子:方法引用通过::将方法隶属和方法自身连接起来,主要分为三类:静态方法参数的实例方法外部的实例方法
该话题由百家号作者山西晚报新媒体「简介:山西最权威,最快速,最全面的媒体平台」整理发布
更多有关Java 8新特性:lambda表达式的话题讨论请关注百家号Lite小程序
「Java 8新特性:lambda表达式」百家号_使用指南:
步骤1:微信扫描「Java 8新特性:lambda表达式」百家号小程序码即可使用;
步骤2:微信搜索「Java 8新特性:lambda表达式」百家号小程序名称即可使用;
步骤3:微信网页访问即速商店-长按识别「Java 8新特性:lambda表达式」百家号小程序码即可使用。
「Java 8新特性:lambda表达式」百家号_服务声明:
本服务由「Java 8新特性:lambda表达式」百家号小程序开发者向微信用户提供,并对本服务信息内容、数据资料及其运营行为等的真实性、合法性及有效性承担全部责任。
"「Java 8新特性:lambda表达式」百家号"由开发者"「Java 8新特性:lambda表达式」百家号"原创首发于微信小程序商店shop.jisuapp.cn,转载请注明出处。
长按保存二维码,在微信app识别
共收到5条评价
5星3条
4星2条
3星0条
2星0条
1星0条
2019-06-25 02:11:58
这个「Java 8新特性:lambda表达式」百家号小程序的功能能满足我使用它的基本诉求,可以可以
2019-06-25 02:09:33
这「Java 8新特性:lambda表达式」百家号小程序用起来很不错,贼6
2019-06-25 02:08:21
很值得使用的「Java 8新特性:lambda表达式」百家号小程序,决定当个忠实粉丝啦~
2019-06-25 02:07:59
昨天用了「Java 8新特性:lambda表达式」百家号微信小程序,亲测好评,给它101分,多1分让它骄傲。
2019-06-25 02:06:42
这么好用的「Java 8新特性:lambda表达式」百家号小程序当然要分享给好朋友啦!