io流,装饰者模式

几年前, Streams API随lambda表达式一起在Java 8中引入。 作为一名训练有素的Java专家,我尝试在我的一些项目中使用此新功能,例如here和here 。 我真的不喜欢它,然后又回到了好的老房子里。 此外,我创建了装饰库Cactoos来取代Guava ,而Guava在很多地方都不是很好。

这是一个原始示例。 假设我们有一些来自某些数据源的测量值,它们都是零到一之间的数字:

Iterable<Double> probes;

现在,我们只需要显示它们的前10个,忽略零和一,然后将它们重新缩放为(0..100) 。 听起来很容易,对吧? 有三种方法可以实现:过程式,面向对象和Java 8方法。 让我们从过程的方式开始:

int pos = 0;
for (Double probe : probes) {if (probe == 0.0d || probe == 1.0d) {continue;}if (++pos > 10) {break;}System.out.printf("Probe #%d: %f", pos, probe * 100.0d);
}

为什么这是一种程序方式? 因为这势在必行。 为什么势在必行? 因为它是程序性的。 不,我在开玩笑。

这是当务之急,因为我们正在向计算机发出有关将哪些数据放入何处以及如何对其进行迭代的指令。 我们不是在声明结果,而是必须构建它。 它可以工作,但不是真正可扩展的。 我们无法参与该算法并将其应用于另一个用例。 我们无法真正轻松地对其进行修改,例如,要从两个来源而不是一个地方获取数字,等等。这是程序性的。 说够了。 不要这样

现在,Java 8为我们提供了Streams API ,该API应该提供一种实现此目的的功能方法。 让我们尝试使用它。

首先,我们需要创建一个Stream的实例, Iterable 不允许我们直接获取它。 然后,我们使用流API来完成这项工作:

StreamSupport.stream(probes.spliterator(), false).filter(p -> p == 0.0d || p == 1.0d).limit(10L).forEach(probe -> System.out.printf("Probe #%d: %f", 0, probe * 100.0d));

这将起作用,但将对所有探针说出Probe #0 ,因为forEach()不适用于索引。 目前是没有这样的事forEachWithIndex()Stream界面的Java 8(和Java 9的太 )。 这是使用原子计数器的解决方法 :

AtomicInteger index = new AtomicInteger();
StreamSupport.stream(probes.spliterator(), false).filter(probe -> probe == 0.0d || probe == 1.0d).limit(10L).forEach(probe -> System.out.printf("Probe #%d: %f",index.getAndIncrement(),probe * 100.0d));

“那是怎么了?” 你可能会问。 首先,看看在Stream接口中找不到正确的方法时,我们遇到麻烦的Stream 。 我们立即摆脱了“流式”范式,回到了良好的旧程序全局变量(计数器)。 其次,我们真的看不到那些filter()limit()forEach()方法内部发生了什么。 它们如何工作? 该文档说,这种方法是“声明性的”,并且Stream接口中的每个方法都返回某个类的实例。 他们是什么班? 只看这段代码,我们一无所知。

此流API的最大问题是Stream接口,它非常庞大!

这两个问题是联系在一起的。 此流API的最大问题是接口Stream –很大。 在撰写本文时,有43种方法。 在一个界面中四十三! 从SOLID到后来的更严格的原则 ,这都与面向对象编程的每条原则 背道而驰 。

实现相同算法的面向对象方法是什么? 这就是我如何使用Cactoos做到的 ,这只是一个集合 原始 简单的Java类:

new And(new Mapped<Double, Scalar<Boolean>>(new Limited<Double>(new Filtered<Double>(probes,probe -> probe == 0.0d || probe == 1.0d),10),probe -> () -> {System.out.printf("Probe #%d: %f", 0, probe * 100.0d);return true;}),
).value();

让我们看看这里发生了什么。 首先, Filtered装饰了我们的可迭代probes以从中取出某些项。 注意, Filtered实现了Iterable 。 然后, Limited (也是一个Iterable )仅取出前十个项目。 然后, Mapped将每个探针转换为Scalar<Boolean>的实例,该实例执行行打印。

最后, And的实例遍历“标量”列表,并要求每个标量返回boolean 。 他们打印行并返回true 。 既然它是trueAnd使用下一个标量进行下一次尝试。 最后,其方法value()返回true

但是,等等,没有索引。 让我们添加它们。 为了做到这一点,我们只使用另一个名为AndWithIndex类:

new AndWithIndex(new Mapped<Double, Func<Integer, Boolean>>(new Limited<Double>(new Filtered<Double>(probes,probe -> probe == 0.0d || probe == 1.0d),10),probe -> index -> {System.out.printf("Probe #%d: %f", index, probe * 100.0d);return true;}),
).value();

现在,我们将探针映射到Func<Integer, Boolean> ,而不是Scalar<Boolean> Func<Integer, Boolean>以使其接受索引。

这种方法的优点在于所有类和接口都很小,这就是为什么它们很容易组合的原因。 为了限制探针的迭代,我们用Limited装饰它; 为了使它过滤,我们用Filtered装饰它; 为了做其他事情,我们创建一个新的装饰器并使用它。 我们并没有像Stream这样的单一接口。

最重要的是,装饰器是一种用于修改集合行为的面向对象的工具,而流是我什至找不到其名称的其他东西。

PS顺便说一下,这就是在Guava的Iterables的帮助下可以实现相同算法的方式:

Iterable<Double> ready = Iterables.limit(Iterables.filter(probes,probe -> probe == 0.0d || probe == 1.0d),10
);
int pos = 0;
for (Double probe : probes) {System.out.printf("Probe #%d: %f", pos++, probe * 100.0d);
}

这是一些面向对象和功能样式的怪异组合。

翻译自: https://www.javacodegeeks.com/2017/10/streams-vs-decorators.html

io流,装饰者模式

io流,装饰者模式_流与装饰器相关推荐

  1. java装饰者模式讲解视频教程_java装饰者模式介绍(图文教程)

    java装饰者模式介绍(图文教程).装饰者模式UML类图: 装饰者模式UML类图 java装饰者模式知识要点 装饰者模式动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. ...

  2. 米线店结账程序 装饰着模式_设计模式——装饰者模式

    <Head First 设计模式> 学习笔记,码云同步更新中 如有错误或不足之处,请一定指出,谢谢~ 目录 查看其它设计模式笔记,点这里→设计模式笔记汇总 装饰者模式 定义: 动态地将责任 ...

  3. 设计模式装饰者模式_装饰者模式如何拯救了我的一天

    设计模式装饰者模式 在工作中,我正在处理庞大的Java代码库,该代码库是由许多不同的开发人员在15年的时间里开发的. 并不是所有的事情都由书来完成,但是同时我通常无法重构遇到的每一个奇怪的事物. 尽管 ...

  4. 米线店结账程序 装饰着模式_实验报告2_装饰者模式

    序号: 姓名: 杨林燕 学号: 106 专业: 软件工程 日期: 成绩: 实验二 装饰者模式的运用 一.实验目的: 装饰者模式动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹 性的替代 ...

  5. 米线店结账程序 装饰着模式_装饰者模式的运用

    实 验 报 告 实验二 装饰者模式的运用 一.实验目的: 装饰者模式动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹 性的替代方案.在熟悉装饰者模式相关理论知识的基础上,使用装设者模式 ...

  6. 米线店结账程序 装饰着模式_设计模式(三)装饰者模式

    装饰者模式是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案.装饰者模式动态地将责任附加到对象身上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案,比生成子类更加灵活. 通常在继承关系 ...

  7. android 装饰着模式,Android与设计模式——装饰者(Decorator)模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替 ...

  8. io读取文件无地址_流的基本概念和IO流入门

    对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能.程序运行需要数据,数据的获取往往需要跟外部系统进行通信,外部系统可能是文件.数据库.其他程序.网络.IO设备等等. ...

  9. python 流式计算框架_流式计算的三种框架:Storm、Spark和Flink

    我们知道,大数据的计算模式主要分为批量计算(batch computing).流式计算(stream computing).交互计算(interactive computing).图计算(graph ...

最新文章

  1. 安装npm_前端开发:node.js的node包管理器npm安装以及使用
  2. 物联网在智慧林业中的应用
  3. 安卓开发——基于ViewPager的图片轮播
  4. 安卓开发之软件维护的策略
  5. 7-3 判断素数 (10 分)
  6. 解决报错ImportError: IProgress not found. Please update jupyter and ipywidgets.
  7. 2021微信大数据挑战赛正式启动报名!
  8. zerglurker的C语言教程001——开发环境搭建
  9. 关于Base64编码(Encode)与解码(Decode)的几种方式,这里面有道道
  10. JQuery 获取 标签中属性值
  11. WinCE6.0双雄 酷派N900/魅族M8对比评测
  12. [题解]斐波那契数列
  13. 利用自定义方法显示数组中的全部数据
  14. 汽车电子行业英文名词
  15. 吴恩达机器学习:方差与偏差
  16. 输入一个字符,判断它如果是小写字母输出其对应大写字母;如果是大写字母输出其对应小写字母;如果是数字输出数字本身;如果是空格,输出“space”;如果不是上述情况,输出“other”。
  17. 1秒计算机格式,嫌修改文件格式麻烦?教你写个简单的bat文件一秒修改格式
  18. MFC关于进程使用:创建、关闭及查询进程
  19. 关于Gorm或ProjectCenter启动时候,没反应的问题解决
  20. 新消费时代,零售业的进与退?

热门文章

  1. 洛谷P3349:小星星(容斥dp)
  2. CF809D-Hitchhiking in the Baltic States【FhqTreap】
  3. 51nod1676-无向图同构【乱搞】
  4. P4245-[模板]任意模数多项式乘法
  5. P3620-[APIO/CTSC2007]数据备份【贪心,堆,链表】
  6. P1375-小猫【卡特兰数】
  7. P1196 ssl1225-银河英雄传说【图论,并查集】
  8. 【贪心】雷达装置(ybtoj 贪心-1-2)
  9. JSP JavaBean
  10. JVM内存管理------GC算法精解(五分钟教你终极算法---分代搜集算法)