比较Java 8中的命令式和功能性算法

Mario Fusco的流行推文令人印象深刻,显示了类似算法的命令性和功能性方法之间的主要区别实际上是:

势在必行–功能分离pic.twitter.com/G2cC6iBkDJ

— Mario Fusco(@mariofusco) 2015年3月1日

两种算法都做同样的事情,它们可能同样快且合理。 但是,一种算法比另一种算法容易编写和读取。 不同之处在于,在命令式编程中,不同的算法要求遍布整个代码块,而在函数式编程中,每个要求都有自己的少量代码行。 相比:

  • 绿色:错误处理
  • 蓝色:停止条件
  • 红色:IO操作
  • 黄色:“业务逻辑”

在jOOQ博客上的其他示例中,函数式编程并不总是能胜过命令式编程:

  • 如何使用Java 8函数式编程生成字母序列
  • 如何使用Java 8流快速替换列表中的元素

但是这是用户Aurora_Titanium的 Stack Overflow的示例 ,其中的区别与Mario Fusco的示例一样明显:

计算数组中的重复值

想法是计算在一组值中重复的所有那些值的总和。 例如,以下数组:

int[] list = new int[]{1,2,3,4,5,6,7,8,8,8,9,10};

…结果应为:

Duplicate: 8. Sum of all duplicate values: 24

势在必行

用户Volkan Ozkan的答案之一采用命令式方法并按以下方式计算总和:

int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 9, 10 
};int sum = 0;
for (int j = 0; j < array.length; j++)
{for (int k = j + 1; k < array.length; k++) {if (k != j && array[k] == array[j]){sum = sum + array[k];System.out.println("Duplicate found: " + array[k]+ " " + "Sum of the duplicate value is " + sum);}}
}

该方法仅适用于已排序的数组,其中重复项紧接着出现。 但是,在这种情况下, 如果性能对于此算法确实很重要 , 那么它可能是性能方面的最佳解决方案。

功能方法

如果您可以接受稍微降低的性能(将int装箱,将它们收集到地图中),也可能是这样,则可以用以下功能性Java-8样式逻辑替换上面难以阅读的代码,更清楚地传达其作用:

int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 9, 10 
};IntStream.of(array).boxed().collect(groupingBy(i -> i)).entrySet().stream().filter(e -> e.getValue().size() > 1).forEach(e -> {System.out.println("Duplicates found for : " + e.getKey()+ " their sum being : " + e.getValue().stream().collect(summingInt(i -> i)));});

或者,并附有说明:

int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 9, 10 
};// Create a Stream<Integer> from your data
IntStream.of(array).boxed()// Group values into a Map<Integer, List<Integer>>.collect(groupingBy(i -> i))// Filter out those map values that have only 
// 1 element in their group.entrySet().stream().filter(e -> e.getValue().size() > 1)// Print the sum for the remaining groups.forEach(e -> {System.out.println("Duplicates found for : " + e.getKey()+ " their sum being : " + e.getValue().stream().collect(summingInt(i -> i)));});

(请注意,函数方法是为每个重复值计算总和,而不是像命令式方法那样计算总和。从原始问题开始,这个要求不是很清楚)

正如我们在博客上的上一篇文章中所指出的那样,通过诸如Java 8 Stream API之类的API进行函数式编程的力量是,我们正在接近SQL风格的声明式编程的表达能力。 我们不再关心记住单个数组索引以及如何计算它们并将中间结果存储到某些缓冲区中。 现在,我们可以专注于真正有趣的逻辑,例如:“什么是重复的?” 或“我对什么感兴趣?”

阅读有关SQL与Java 8 Streams相比的更多信息:Java 8 Streams中的常见SQL子句及其等效项

翻译自: https://www.javacodegeeks.com/2015/09/comparing-imperative-and-functional-algorithms-in-java-8.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357333.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mvc的视图中显示DataTable的方法

mvc的视图中显示DataTable的方法&#xff1a; 不断的循环画出table {ViewBag.Title "ShowDataTable"; } using System.Data; model Models.ConModel{var table Model.ExcelTable as DataTable; }<script src"~/Scripts/My97DatePicker/WdatePicker.js"…

rem,em,px,rpx等

1、任意浏览器的默认字体高都是16px。谷歌浏览器显示的最小字体大小是12px。 exp&#xff1a;突破谷歌浏览器显示12px限制。 &#xff08;1&#xff09;、<div>文本</div> 文本嵌套块标签&#xff0c;这是因为缩放只对有宽高的标签有效&#xff0c;缩放的时候也是…

python 列表 字典 读写文件:pickle模块的基本使用

建议大家使用cPickle&#xff0c;速度更快&#xff01;&#xff01;&#xff01; python数据持久存储&#xff1a;pickle模块的基本使用&#xff08;转载&#xff09; 作者: pzxbc出处: http://pzxbc.cnblogs.com/本文版权归作者和博客园共有&#xff0c;欢迎转载&#xff0c;但…

first-child、first-of-type等属性的差别

1、xxx:first-child 伪类 xxx作为第一个子元素 //p元素作为第一个子元素的都会变色 p:first-child { background:yellow; } //p作为父元素的 第一个子元素。不要求第一个元素的类型 p>:first-child {background:yellow; }//p作为父元素的 第一个子元素。要求第一个元素的类…

js 手机端触发事事件、javascript手机端/移动端触发事件

处理Touch事件能让你跟踪用户的每一根手指的位置。你可以绑定以下四种Touch事件: touchstart: // 手指放到屏幕上的时候触发 touchmove: // 手指在屏幕上移动的时候触发 touchend: // 手指从屏幕上拿起的时候触发 touchcancel: // 系统取消touch事件的时候触发。至于系统…

java 8 lambda_Java 8的烹调方式– Lambda项目

java 8 lambda什么是project lambda &#xff1a;Project lambda是用于以Java语言语法启用lambda表达式的项目。 Lambda表达式是功能编程语言&#xff08;如lisp&#xff09;中的主要语法。 Groovy将是支持lambda表达式&#xff08;也称为闭包&#xff09;的java的最接近亲戚。…

我的Serverless实战——引领云计算的下一个十年

前言&#xff1a;如今&#xff0c;越来越多的大厂企业开始大规模使用Serverless&#xff0c;处于变革中的开发者&#xff0c;大多已从观望状态转向尝试阶段&#xff0c;越来越多Serverless落地场景被解锁。作为基础研发底座&#xff0c;越来越多企业开始接受Serverless&#xf…

各种边距clientWidth、offsetWidth、scrollWidth、clientLeft、getBoundingClientRect详解

1、clientWidth、offsetWidth、scrollWidth <!DOCTYPE html> <html><head><meta charset"utf-8" /><style>#box1 {padding: 50px;position: static;}#box {border: 1px solid red;overflow: scroll;height: 200px;width: 500px;}#con…

encodeURIComponent的使用

URL 元字符&#xff1a;分号&#xff08;;&#xff09;&#xff0c;逗号&#xff08;,&#xff09;&#xff0c;斜杠&#xff08;/&#xff09;&#xff0c;问号&#xff08;?&#xff09;&#xff0c;冒号&#xff08;:&#xff09;&#xff0c;at&#xff08;&#xff09;&a…

如何以及何时使用枚举和注释

本文是我们名为“ 高级Java ”的学院课程的一部分。 本课程旨在帮助您最有效地使用Java。 它讨论了高级主题&#xff0c;包括对象创建&#xff0c;并发&#xff0c;序列化&#xff0c;反射等。 它将指导您完成Java掌握的过程&#xff01; 在这里查看 &#xff01; 目录 1.简…

花了两天时间用html+css+js做了一个网页版坦克大战游戏

大家好&#xff0c;我是孙叫兽&#xff0c;本期内容给大家分享如何用htmlcssjavaScript去做一个简易网页版坦克游戏。 目录 坦克游戏玩法及介绍 项目结构 源码地址&#xff1a; 坦克游戏玩法及介绍 我们先来看一下首页。 打开这个首页很简单&#xff0c;基本是上面这个样子&…

软件工程第一次冲刺进度条(1-10天)

第一天&#xff08;4.20&#xff09;昨天做了什么今天做了什么遇到的问题配置安装所需要的环境和相关软件 查询android关于界面编程与视图的相关资料并且初步编写代码 配置虚拟机的时候电脑上总是失败第二天&#xff08;4.21&#xff09;昨天做了什么今天做了什么遇到的问题查询…

css基础过渡与动画与应用于vue、react

一、css属性过渡transition 1、解释&#xff1a; 使用该属性后变化不会在一瞬间完成&#xff0c;会有一个连续的变化效果。第一个参数设置哪些属性变化时需要有连续的效果。 不论用什么方式使属性的值发生变化&#xff0c;transition都会生效。 2、语法&#xff1a; trans…

Android项目开发填坑记-Fragment的onAttach

背景 现在Android开发多使用一个Activity管理多个Fragment进行开发&#xff0c;不免需要两者相互传递数据&#xff0c;一般是给Fragment添加回调接口&#xff0c;让Activity继承并实现。 回调接口一般都写在Fragment的onAttach()方法中&#xff0c;Fragment 3.0 的onAttach()方…

前端开发——移动端及响应式布局解决办法总结(适配)

问题分析:前端开发一个产品(网站、系统、APP等)会遇到的一个难点就是适配问题,比如开发一个网站,你在一个页面开发的时候从视觉看起来没什么异样,换个不同分别率的设备,电脑,手机等,发现样式全乱了,这个不是我们想要的结果,所以,浏览器适配,响应式布局就显得尤为重…

来点小技巧,Array.filter(Boolean)、 [].slice.call(this)等等

1、Array.filter(Boolean) 移除所有的 ”false“ 类型元素 (false, null, undefined, 0, NaN or an empty string)。 Boolean 是一个函数相当于直接传了个函数进去 Array.filter(Boolean)Array.filter(i>Boolean(i)) Array.filter(i>i) let a [1, 2, b, 0, {}, , N…

设置文字多行显示溢出显示省略号

#news_text { border: 1px solid red; width: 200px; word-break: break-all; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; /*这里可以设置文本显示的行数*/ overflow: hidden; }<div id"news_text"&g…

vue项目有几个接口content Download时间特别长的解决办法

做的可视化地图项目&#xff0c;有几个接口加载比较慢&#xff0c;大概16S左右&#xff0c;第一次加载接近一分钟&#xff0c;这谁能受得了。 对比了正式环境和测试环境&#xff0c;这个接口数据量一样&#xff0c;就是在测试服务器比较慢&#xff0c;排除滚动插件及其它的影响…

Java中集合的自定义运算符

总览 操作员重载有多种语言可用。 Java对String类型的运算符的支持对运算符的重载非常有限。 我们可以利用其他语言支持运算符的不同方式&#xff0c;但是可以在Java中实现一个使用Java已经使用的约定的实现。 获取&#xff0c;设置和放置操作 集合的运算符重载的一个常见示例…

【Java从入门到天黑|03】JavaSE入门之流程控制

大家好,我是孙叫兽,本期内容给大家分享一下JavaSE入门之流程控制。 用户交互Scanner 1、Scanner对象 之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。java.util.Scanner 是 Java5 的新特征,我们可以通过…