Java8函数式编程和新特性lambda的示例分析


小编给大家分享一下Java8函数式编程和新特性lambda的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!函数式编程更多时候是一种编程的思维方式,是种方法论。函数式与命令式编程的区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉代码要怎么做。说白了,函数式编程是基于某种语法或调用API去进行编程。例如,我们现在需要从一组数字中,找出最小的那个数字,若使用用命令式编程实现这个需求的话,那么所编写的代码如下:而使用函数式编程进行实现的话,所编写的代码如下:从以上的两个例子中,可以看出,命令式编程需要自己去实现具体的逻辑细节。而函数式编程则是调用API完成需求的实现,将原本命令式的代码写成一系列嵌套的函数调用,在函数式编程下显得代码更简洁、易懂,这就是为什么要使用函数式编程的原因之一。所以才说函数式编程是告诉代码你要做什么,而命令式编程则是告诉代码要怎么做,是一种思维的转变。说到函数式编程就不得不提一下lambda表达式,它是函数式编程的基础。在Java还不支持lambda表达式时,我们需要创建一个线程的话,需要编写如下代码:而使用lambda表达式一句代码就能完成线程的创建,lambda强调了函数的输入输出,隐藏了过程的细节,并且可以接受函数当作输入(参数)和输出(返回值):注:箭头的左边是输入,右边则是输出。该lambda表达式的作用其实就是返回了Runnable接口的实现对象,这与我们调用某个方法获取实例对象类似,只不过是将实现代码直接写在了lambda表达式里。我们可以做个简单的对比:1.函数接口,接口只能有一个需要实现的方法,可以使用@FunctionalInterface 注解进行声明。如下:使用lambda表达式获取该接口的实现实例的几种写法:2.比较重要的一个接口特性是接口的默认方法,用于提供默认实现。默认方法和普通实现类的方法一样,可以使用this等关键字:之所以说默认方法这个特性比较重要,是因为我们借助这个特性可以在以前所编写的一些接口上提供默认实现,并且不会影响任何的实现类以及既有的代码。例如我们最熟悉的List接口,在JDK1.2以来List接口就没有改动过任何代码,到了1.8之后才使用这个新特性增加了一些默认实现。这是因为如果没有默认方法的特性的话,修改接口代码带来的影响是巨大的,而有了默认方法后,增加默认实现可以不影响任何的代码。3.当接口多重继承时,可能会发生默认方法覆盖的问题,这时可以去指定使用哪一个接口的默认方法实现,如下示例:我们本小节来看看JDK8里自带了哪些重要的函数接口:可以看到上表中有好几个接口,而其中最常用的是Function接口,它能为我们省去定义一些不必要的函数接口,减少接口的数量。我们使用一个简单的例子演示一下 Function 接口的使用:运行以上例子,控制台输出如下:我的存款: 人民币 99,999,999若在这个例子中不使用Function接口的话,则需要自行定义一个函数接口,并且不支持链式操作,如下示例:然后我们再来看看Predicate接口和Consumer接口的使用,如下示例:运行以上例子,控制台输出如下:false这是输入的数据这些接口一般有对基本类型的封装,使用特定类型的接口就不需要去指定泛型了,如下示例:运行以上代码,控制台输出如下:false输入的数据是:123有了以上接口示例的铺垫,我们应该对函数接口的使用有了一个初步的了解,接下来我们演示剩下的函数接口使用方式:运行以上代码,控制台输出如下:提供的数据是:11计算结果为:20计算结果为:100而BiFunction接口就是比Function接口多了一个输入而已,如下示例:运行以上代码,控制台输出如下:小明的存款: 99,999,999在学习了lambda表达式之后,我们通常会使用lambda表达式来创建匿名方法。但有的时候我们仅仅是需要调用一个已存在的方法。如下示例:在jdk8中,我们可以通过一个新特性来简写这段lambda表达式。如下示例:这种特性就叫做方法引用(Method Reference)。方法引用的标准形式是:类名::方法名。(注意:只需要写方法名,不需要写括号)。目前方法引用共有以下四种形式:下面我们用一个简单的例子来演示一下方法引用的几种写法。首先定义一个实体类:通过方法引用来调用该实体类中的方法,代码如下:最后需要说一句的就是能够使用方法引用的地方就尽量不要使用lambda表达式,这样就不会多生成一个类似 lambda$0这样的函数,能够减少一些资源的开销。通过以上的例子,我们知道之所以能够使用Lambda表达式的依据是必须有相应的函数接口。这一点跟Java是强类型语言吻合,也就是说你并不能在代码的任何地方任性的写Lambda表达式。实际上Lambda的类型就是对应函数接口的类型。Lambda表达式另一个依据是类型推断机制,在上下文信息足够的情况下,编译器可以推断出参数表的类型,而不需要显式指名。
所以说 Lambda 表达式的类型是从 Lambda 的上下文推断出来的,上下文中 Lambda 表达式需要的类型称为目标类型,如下图所示:接下来我们使用一个简单的例子,演示一下 Lambda 表达式的几种类型推断,首先定义一个简单的函数接口:示例代码如下:Lambda表达式类似于实现了指定接口的内部类或者说匿名类,所以在Lambda表达式中引用变量和我们在匿名类中引用变量的规则是一样的。如下示例:值得一提的是,在JDK1.8之前我们一般会将匿名类里访问的外部变量设置为final,而在JDK1.8里默认会将这个匿名类里访问的外部变量给设置为final。例如我现在改变str变量的值,ide就会提示错误:至于为什么要将变量设置final,这是因为在Java里没有引用传递,变量都是值传递的。不将变量设置为final的话,如果外部变量的引用被改变了,那么最终得出来的结果就会是错误的。下面用一组图片简单演示一下值传递与引用传递的区别。以列表为例,当只是值传递时,匿名类里对外部变量的引用是一个值对象:若此时list变量指向了另一个对象,那么匿名类里引用的还是之前那个值对象,所以我们才需要将其设置为final防止外部变量引用改变:而如果是引用传递的话,匿名类里对外部变量的引用就不是值对象了,而是指针指向这个外部变量:所以就算list变量指向了另一个对象,匿名类里的引用也会随着外部变量的引用改变而改变:在函数式编程中,函数既可以接收也可以返回其免费云主机域名他函数。函数不再像传统的面向对象编程中一样,只是一个对象的工厂或生成器,它也能够创建和返回另一个函数。返回函数的函数可以变成级联 lambda 表达式,特别值得注意的是代码非常简短。尽管此语法初看起来可能非常陌生,但它有自己的用途。级联表达式就是多个lambda表达式的组合,这里涉及到一个高阶函数的概念,所谓高阶函数就是一个可以返回函数的函数,如下示例:这里的 y -> x + y 是作为一个函数返回给上一级表达式,所以第一级表达式的输出是 y -> x + y这个函数,如果使用括号括起来可能会好理解一些:级联表达式可以实现函数柯里化,简单来说柯里化就是把本来多个参数的函数转换为只有一个参数的函数,如下示例:如果大家想学习以上路线内容,在此我向大家推荐一个架构学习交流群。交流学习群号874811168 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多函数柯里化的目的是将函数标准化,函数可灵活组合,方便统一处理等,例如我可以在循环里只需要调用同一个方法,而不需要调用另外的方法就能实现一个数组内元素的求和计算,代码如下:级联表达式和柯里化一般在实际开发中并不是很常见,所以对其概念稍有理解即可,这里只是简单带过。以上是“Java8函数式编程和新特性lambda的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注百云主机行业资讯频道!

相关推荐: css怎么在页面上放置背景图像

这篇文章主要介绍css怎么在页面上放置背景图像,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! 示意:您须要把 bac千克round-attachment 属性配置为 “fixed”,才略保证该属性在 Firefox 和 Opera 中畸…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 09/08 17:23
Next 09/08 17:23

相关推荐