前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >函数式编程思维在三行代码情书中的应用

函数式编程思维在三行代码情书中的应用

作者头像
CodeSheep
发布2018-06-07 13:40:59
9820
发布2018-06-07 13:40:59
举报

如今主流的编程语言,函数式编程范式或多或少都融入其中成了“标配”,或者说主流语言都在进行函数式方面的扩充,这是一个大趋势。以Java为例,随着 Lambda块 和 Stream API 等这种高阶函数的加持,Java总算是装备了函数式这一利器;博大精深的C++也在2011版的语言标准里加入了Lambda块的支持;再比如前一段时间我初步体验了的 Groovy语言,虽然其运行于JVM之上,然而其对 动态语言、函数式编程范式 以及 元编程功能 的加持所带来的表现力和简洁性可以说甩了Java几条街,可以利用Groovy的所有动态功能构建高性能的JVM应用、将开发效率提高几个数量级。

42:9
42:9

函数式编程概述

如今主流的编程语言,函数式编程范式或多或少都融入其中成了“标配”,或者说主流语言都在进行函数式方面的扩充,这是一个大趋势。以Java为例,随着 Lambda块Stream API 等这种高阶函数的加持,Java总算是装备了函数式这一利器;博大精深的C++也在2011版的语言标准里加入了Lambda块的支持;再比如前一段时间我初步体验了的 Groovy语言,虽然其运行于JVM之上,然而其对 动态语言函数式编程范式 以及 元编程功能 的加持所带来的表现力和简洁性可以说甩了Java几条街,可以利用Groovy的所有动态功能构建高性能的JVM应用、将开发效率提高几个数量级。语言的例子有很多,我不一一枚举。

为什么要使用函数式编程范式

这里讲几个函数式编程的典型特点,区别的对象那就是传统的命令式编程

命令式编程 VS 函数式编程
命令式编程 VS 函数式编程
  • 0x01. 更高层次的抽象(高阶函数)

用高阶抽象来取代基本的控制结构本身就是一个全新的思考方式,这样可以让开发者聚焦精力于业务场景而无需费心复杂地层运作

举个栗子:将一个字符串集合中的所有单词转为大写,我们用Java语言来实现

如果按照传统的命令式编程的解法,那接下来不出意外我们得来写循环、遍历这种迭代操作了:

123

for (int i=0; i<wordList.size(); i++) { wordList.get(i).toUpperCase();}

但如果使用Java的函数式编程范式,一切都是那么的优雅,一句话搞定

1

wordList.stream.map( w -> w.toUpperCase() )

这里的map()函数就是所谓的高阶函数,我们用高阶函数代替了底层的迭代,因为我们并没有处理细节,我们仅仅定义了映射的逻辑,迭代由高阶函数来自动完成!

  • 0x02. 提升代码信噪比(简洁性)

区别于面向对象语言用抽象来封装不确定因素,函数式编程通过尽量减少不确定因素来使代码极度简洁

上面的例子对于本条优点的展现我想应该也不必多说了

  • 0x03. 控制权转交于运行时(动态性)

区别于传统的编译形语言,配备函数式编程范式的动态语言更多的将控制权转交到语言运行时手里,获得的则是更高的灵活性、表现力和性能权衡。

这三点优点将在接下来的例子中切实的感受并领会!

函数式编程例析

举例1:词频统计

做的事情很简单:给定一个单词集合,统计出集合中除了助词(如ofonthe等)之外的单词出现的频次,不区分大小写

命令式解法: 至少分为以下几大步

  • 先进行循环迭代
  • 然后统一将单词转为小写
  • 然后判断单词是否是助词
  • 最后进行词频统计
代码语言:javascript
复制
public class WordCount {    // 定义一个助词集合,这些单词不参与计数    private Set<String> auxiliaryWordSet = new HashSet<String>() {{       add("of"); add("the"); add("to"); add("and"); add("so"); add("are”);    }};    // 传统命令式解法实现的词频统计函数    public Map doWordCount( List<String> context ) {        Map<String,Integer> result = new HashMap<String, Integer>();        for ( String word:context ) {  // 循环迭代            String lowerCaseWord = word.toLowerCase();  // 将单词统一转换为小写            if( !auxiliaryWordSet.contains(lowerCaseWord) ) {                if( null == result.get(lowerCaseWord) )                    result.put( lowerCaseWord, 1 );                else                    result.put( lowerCaseWord, result.get(lowerCaseWord)+1 );            }        }        return result;    }    // main() 函数    public static void main(String[] args) {        List<String> wordList = new ArrayList<String>() {{            add("The"); add("Products"); add("of"); add("Samsung"); add("and"); add("Apple”);            add("are"); add("so"); add("amazing"); add("especially"); add("Apple”);        }};        WordCount wordCount = new WordCount();        Map res = wordCount.doWordCount( wordList );        System.out.print(res); // 打印:{apple=2, amazing=1, samsung=1, especially=1, products=1}    }}

函数式解法:

如果我们用Java的Stream API和Lambda块所构成的函数式范式来重写 doWordCount() 函数,一切都将如此简洁:

函数式解法1: Java Steam API 和 Lambda块实现

12345

public String connectWord( List<String> context ) { return context.stream().filter( w -> w.length()>1 ) .map( w -> capitalizeFirstLetter(w) ) .collect( Collectors.joining("-") );}

我什么都不想说了,这不要太简洁好吧!

函数式解法2: Groovy语言实现

12345

public String connectWord( context ) { context.findAll { it.length() >1 } .collect { it.capitalize() } .join ‘-‘}

关于Groovy语言的初体验,可以参考我的文章:Groovy初体验:构建高性能JVM应用

函数式最佳实践:高效编写三行情书

还记得去年的520,为了表达心中对于老婆无限的、无法表达的爱,我想写一封不超过三行的代码情书,我更想用尽可能短的代码来尽可能多地表达,于是我选择了函数式编程。

我的520三行代码情书在此:

代码语言:javascript
复制
public TimeRiver timeFlow( List<DaysMeetYou> days ) {    return (TimeRiver)days.stream()        .filter( n->theDaysNotWithYou(n) )        .map( e->accompanyByMyLove(e) )        .collect( Collectors.joining(“”) );}
我的520三行代码情书
我的520三行代码情书

后记

文中提到的Groovy动态编程语言,作者体验过一点,可以参考:Groovy初体验:构建高性能JVM应用

如果有兴趣,也来看看作者一些关于容器化、微服务化方面的文章:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-05-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 函数式编程概述
  • 为什么要使用函数式编程范式
  • 函数式编程例析
    • 举例1:词频统计
    • 函数式最佳实践:高效编写三行情书
    • 后记
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档