通过实例学习Either 树和模式匹配_java

来源:脚本之家  责任编辑:小易  

行道树精神就是默默奉献,认真体会这种精神的深层含义。你可以联系你的生活,如:与家人、朋友、陌生人等人的一些奉献精神:他们是怎么做的。然后再谈谈自己的感受:你该怎么做?从小事做起,从生活的一点一滴做起?按着这个步棸写,相信你会写好的www.zgxue.com防采集请勿采集本网。

前言

在这一期的文章中,我将继续介绍 Either,使用它构建树形结构,该结构允许我模拟 Scala 的模式匹配来构建遍历方法。

说到这里,于博士还提到,随着时代的发展,同学们应当越来越重视英语的学习,以便日后同国际上进行交流。于博士在海外曾在招生办工作过,于是我希望他能够评价一下母校的教学。没想到他的第一句话是,我不

在 Java 中使用泛型数据,Either 会成为接收两种类型之一的单一数据结构,这两种类型保存在 left 和 right 部分中。

通过加速度计算速度,通过速度计算位移。D、电磁学上的意义: 计算电场强度分布;计算电势分布;计算磁感应强度分布;计算电磁场能量;计算感生电动势等等。第三方面:具体极限的例子说明 为了说明清楚,

在上一期文章的罗马数字解析器示例中,Either 保存了 Exception(左侧)或 Integer(右侧),如图 1 所示:

桑代克的联结理论来解释是可按照教材上的定义的基础-经验引起的变化是如何发生的一种学习理论。联结理论的前提是认为人或动物的行为是由无数刺激和反应的联系单位所组成,每一行动都是对一定

图 1. Either 抽象保存了两种类型的其中之一

自己把握好自己的情绪,可以通过与朋友聊天来舒缓自己

在本示例中,Either以如下的方式被填充:

你这个口气也真大,你要学,然后还要别人找资料,你真要学习的话,去官方网上把jar下载下来,自己手动建个框架的运行环境,这样你才能有进步。

Either<Exception, Integer> result = RomanNumeralParser.parseNumber("XLII");

Scala 模式匹配

Scala 的众多出色功能之一就是能够使用 模式匹配 进行调度(参阅 参考资料)。与描述相比,演示更简单一些,因此我们会考虑清单 1 中的函数,将数字分数转换为字母分数:

清单 1. 使用 Scala 模式匹配根据分数调度字母分数

val VALID_GRADES = Set("A", "B", "C", "D", "F")def letterGrade(value: Any) : String = value match {case x:Int if (90 to 100).contains(x) => "A"case x:Int if (80 to 90).contains(x) => "B"case x:Int if (70 to 80).contains(x) => "C"case x:Int if (60 to 70).contains(x) => "D"case x:Int if (0 to 60).contains(x) => "F"case x:String if VALID_GRADES(x.toUpperCase) => x.toUpperCase}printf("Amy scores %d and receives %s\n", 91, letterGrade(91))printf("Bob scores %d and receives %s\n", 72, letterGrade(72))printf("Sam never showed for class, scored %d, and received %s\n", 44, letterGrade(44))printf("Roy transfered and already had %s, which translated as %s\n","B", letterGrade("B"))

在 清单 1 中,函数的整个正文由应用于 value 的 match 构成。对于每个选项,模式防护 允许我根据除参数类型以外的条件筛选匹配内容。这种语法的优势是一个干净的选项分区,而不是一系列复杂的 if 语句。

模式匹配与 Scala 的 case 类一同工作,该类是具有特殊属性的类 (包括执行模式匹配的能力),以消除决策序列。考虑匹配颜色组合,如清单 2 所示:

清单 2. 在 Scala 中匹配 case 类

class Color(val red:Int, val green:Int, val blue:Int)case class Red(r:Int) extends Color(r, 0, 0)case class Green(g:Int) extends Color(0, g, 0)case class Blue(b:Int) extends Color(0, 0, b)def printColor(c:Color) = c match {case Red(v) => println("Red: " + v)case Green(v) => println("Green: " + v)case Blue(v) => println("Blue: " + v)case col:Color => {print("R: " + col.red + ", ")print("G: " + col.green + ", ")println("B: " + col.blue)}case null => println("invalid color")}

在 清单 2 中,我创建了一个基本 Color 类,然后与 case 类一样,创建了一个特殊的单一颜色版本。当确定将哪种颜色传递给函数时,我使用了 match,根据所有可用选项进行模式匹配,这些可用选项中包括最后一个 case,它将处理 null。

Java 没有提供模式匹配,因此它无法复制 Scala 的创建清晰可读的调度代码的能力。但是,通过结合使用泛型数据结构和众所周知的数据结构,可以实现更加接近的能力,这又将我带回了 Either。

Either 树

可以建模一个具有三个抽象的树形数据结构,如表 1 所示:

Empty 单元中不包含任何值
Leaf 单元中拥有一个特殊数据类型值
Node 指向其他 叶 或 节点

但是为了方便起见,我将在本例中使用来自 Functional Java 框架的一个类。从概念上讲,Either 抽象扩展到了所需的方面。例如,您可以考虑声明 Either<Empty, Either<Leaf, Node>>,这将创建一个三部分的数据结构,如图 2 所示:

图 2. Either<Empty, Either<Leaf, Node>> 的数据结构

执行了三个树抽象的 Either 实现之后,我定义了树,如清单 3 所示:

清单 3. 基于 Either 的树

import fj.data.Either;import static fj.data.Either.left;import static fj.data.Either.right;public abstract class Tree {private Tree() {}public abstract Either<Empty, Either<Leaf, Node>> toEither();public static final class Empty extends Tree {public Either<Empty, Either<Leaf, Node>> toEither() {return left(this);}public Empty() {}}public static final class Leaf extends Tree {public final int n;public Either<Empty, Either<Leaf, Node>> toEither() {return right(Either.<Leaf, Node>left(this));}public Leaf(int n) { this.n = n; }}public static final class Node extends Tree {public final Tree left;public final Tree right;public Either<Empty, Either<Leaf, Node>> toEither() {return right(Either.<Leaf, Node>right(this));}public Node(Tree left, Tree right) {this.left = left;this.right = right;}}}

清单 3 中的抽象 Tree 类定义了三个 final 具体类:Empty、Leaf 和 Node。从内部讲,Tree 类使用 3 个插槽的 Either,如 图 2 所示,实现这样一种规则,即最左侧的插槽总是保存 Empty,中间插槽保存 Leaf,而最右侧的插槽保存 Node。方法是:请求每个类都实现 toEither() 方法,返回该类型相应的 “插槽”。从传统计算机科学方面讲,数据结构中的每个 “单元” 都是一个 union,旨在保存任意给定时间三种可能类型的其中一种类型。

考虑到此树形结构和其内部结构基于 <Either, <Left, Node>> 的事实,我可以通过模拟模式匹配来访问树中的每个元素。

树遍历的模式匹配

Scala 的模式匹配鼓励您思考离散情况。Functional Java 的 Either 实现中的 left() 和 right() 方法都实现了 Iterable 接口;这允许我编写支持模式匹配的代码来确定树的深度,如清单 4 所示:

清单 4. 使用类似模式匹配的语法检查树的深度

static public int depth(Tree t) {for (Empty e : t.toEither().left())return 0;for (Either<Leaf, Node> ln: t.toEither().right()) {for (Leaf leaf : ln.left())return 1;for (Node node : ln.right())return 1 + max(depth(node.left), depth(node.right));}throw new RuntimeException("Inexhaustible pattern match on tree");}

清单 4 中的 depth() 方法是一个递归深度查找函数。因为我的树基于一个具体的数据结构(<Either, <Left, Node>>),所以我可以将每个 “插槽” 视为一个具体情况。如果单元为空,则树枝没有深度。如果单元为叶,则将它视为树级别。如果单元为节点,那么我会知道应该以递归方式搜索左侧和右侧,然后添加 1 进行另一次递归。

我还可以使用相同的模式匹配语法来执行树的递归搜索,如清单 5 所示:

清单 5. 在树中确定是否存在元素

static public boolean inTree(Tree t, int value) {for (Empty e : t.toEither().left())return false;for (Either<Leaf, Node> ln: t.toEither().right()) {for (Leaf leaf : ln.left())return value == leaf.n;for (Node node : ln.right())return inTree(node.left, value) | inTree(node.right, value);}return false;}

与之前一样,我在数据结构中为每个可能的 “插槽” 指定一个 return 值。如果遇到一个空单元,则会返回 false;我的搜索会失败。对于叶,我会检查传递的值,如果它们匹配则返回 true。否则,在遇到节点时,我会遍历树,使用 |(非短路的 or 运算符)来组合返回的布尔值。

要查看实际的树创建和搜索,请考虑清单 6 中的单元测试:

清单 6. 测试树可搜索性

@Testpublic void more_elaborate_searchp_test() {Tree t = new Node(new Node(new Node(new Node(new Node(new Leaf(4),new Empty()), new Leaf(12)), new Leaf(55)), new Empty()), new Leaf(4));assertTrue(inTree(t, 55));assertTrue(inTree(t, 4));assertTrue(inTree(t, 12));assertFalse(inTree(t, 42));}

在 清单 6 中,我构建了树,然后调查了是否存在元素。inTree() 方法返回 true,如果其中一个叶等于搜索值,并且 true 传播了递归调用堆栈,这是因为 | ("or") 运算符,如 清单 5 所示。

清单 5 中的示例确定了元素是否出现于树中。更复杂的版本还会检查出现的次数,如清单 7 所示:

清单 7. 查找在树中出现的次数

static public int occurrencesIn(Tree t, int value) {for (Empty e: t.toEither().left())return 0;for (Either<Leaf, Node> ln: t.toEither().right()) {for (Leaf leaf : ln.left())if (value == leaf.n) return 1;for (Node node : ln.right())return occurrencesIn(node.left, value) + occurrencesIn(node.right, value);}return 0;}

在 清单 7 中,我为每个匹配的叶返回了 1,这使我可以计算树中每个数字出现的次数。

清单 8 展示了复杂树中 depth()、inTree() 和 occurrencesIn() 的测试:

清单 8. 在复杂树中测试深度、存在状况和出现次数

@Testpublic void multi_branch_tree_test() {Tree t = new Node(new Node(new Node(new Leaf(4),new Node(new Leaf(1), new Node(new Node(new Node(new Node(new Node(new Node(new Leaf(10), new Leaf(0)),new Leaf(22)), new Node(new Node(new Node(new Leaf(4), new Empty()),new Leaf(101)), new Leaf(555))),new Leaf(201)), new Leaf(1000)),new Leaf(4)))),new Leaf(12)), new Leaf(27));assertEquals(12, depth(t));assertTrue(inTree(t, 555));assertEquals(3, occurrencesIn(t, 4));}

由于我对树的内部结构应用了正则性,因此我可以在遍历期间分析树,方法是思考每种情况,如元素类型所示。该语法尽管不像完全成熟的 Scala 模式匹配一样强大,但是与 Scala 出乎意料的接近。

结束语

在这一期的文章中,我介绍了如何在树遍历期间,对启用了 Scala 风格的模式匹配应用正则性,以及如何利用泛型 Iterable 的一些固有属性、Functional Java 的 Either 类和其他一些元素来模拟强大的 Scala 功能。

FMEA的具体内容 失效模式和效果分析FMEA有三种类型,分别是系统FMEA、设计FMEA和工艺FMEA,确定产品需要涉及的技术能够出现的问题 包括下述各个方面:需要设计的新系统、产品和工艺;对现有设计和工艺的改进;在新的应用中或新的环境下,对以前的设计和工艺的保留使用;形成FMEA团队。理想的FMEA团队应包括设计、生产、组装、质量控制、可靠性、服务、采购、测试 以及供货方等所有有关方面的代表。记录FMEA的序号日期和更改内容 保持FMEA始终是一个根据实际情况变化的实时现场记录,需要强调的是,FMEA文件必须包括创建和更新的日期。创建工艺流程图 工艺流程图应按照事件的顺序和技术流程的要求而制定,实施FMEA需要工艺流程图,一般情况下工艺流程图不要轻易变动。列出所有可能的失效模式效果和原因 对于工艺流程中的每一项工艺,应确定可能发生的失效模式.如就表面贴装工艺(SMT)而言,涉及的问题可能包括,基于工程经验的焊球控制、焊 膏控制、使用的阻焊剂(soldermask)类型、元器件的焊盘图形设计等。对于每一种失效模式,应列出一种或多种可能的失效影响,例如,焊球可能要影响到产品长期的可靠性,因此在可能的影响方面应该注明。对于每一种失效模式,应列出一种或多种可能的失效原因.例如,影响焊球的可能因素包括焊盘图形设计、焊膏湿度过大以及焊膏量控制等。现有的工艺控制手段是基于目前使用的检测失效模式的方法,来避免一些根本的原因。例如,现有的焊球工艺控制手段可能是自动光学检测(AOI),或者对焊膏记录良好的控制过程。对事件发生频率严重程度和检测等级进行排序 严重程度是评估可能的失效模式对于产品的影响,10为最严重,1为没有影响;事件发生的频率要记录特定的失效原因和机理多长时间发生一次以及发生的几率。如果为10,则表示几乎肯定要发生,工艺能力为0.33或者ppm大于10000。检测等级是评估所提出的工艺控制检测失效模式的几率,列为10表 示不能检测,1表示已经通过目前工艺控制的缺陷检测。计算风险优先数RPN(riskprioritynumber)。RPN是事件发生的频率、严重程度和检测等级三者乘积,用来衡量可能的工艺缺陷,以便采取可能的预防措施减少关键的工艺变化,使工艺更加可靠。对于工艺的矫正首先应集中在那些最受关注和风险程度最高的环节。RPN最坏的情况是1000,最好的情况是1,确定从何处着手的最好方式是利用RPN的pareto图,筛选那些累积等级远低于80%的项目。推荐出负责的方案以及完成日期,这些推荐方案的最终目的是降低一个或多个等级。对一些严重问题要时常考虑拯救方案,如:一个产品的失效模式影响具有风险等级9或10;一个产品失效模式/原因事件发生以及严重程度很高;一个产品具有很高的RPN值等等。在所有的拯救措施确和实施后,允许有一个稳定时期,然后还应该对修订的事件发生的频率、严重程度和检测等级进行重新考虑和排序。FMEA的应用 FMEA实际上意味着是事件发生之前的行为,并非事后补救。因此要想取得最佳的效果,应该在工艺失效模式在产品中出现之前完成。产品开发的5个阶段包括:计划和界定、设计和开发、工艺设计、预生产、大批量生产。作为一家主要的EMS提供商,Flextronics International已经在生产工艺计划和控制中使用了FMEA管理,在产品的早期引入FMEA管理对于生产高质量的产品,记录并不断改善工艺非常关键。对于该公司多数客户,在完全确定设计和生产工艺后,产品即被转移到生产中心,这其中所使用的即是FMEA管理模式。手持产品FMEA分析实例 失效模式和效果分析在该新产品介绍(NPI)发布会举行之后,即可成立一个FMEA团队,包括生产总监、工艺工程师、产品工程师、测试工程师、质量工程师、材料采购员以及项目经理,质量工程师领导该团队。FMEA首次会议的目标是加强初始生产工艺MPI(Manufacturing Process Instruction)和测试工艺TPI(Test Process Instruction)中的质量控制点同时团队也对产品有更深入的了解,一般首次会议期间和之后的主要任务包括:1.工艺和生产工程师一步一步地介绍工艺流程图,每一步的工艺功能和要求都需要界定。2.团队一起讨论并列出所有可能的失效模式、所有可能的影响、所有可能的原因以及目前每一步的工艺控制,并对这些因素按RPN进行等级排序。例如,在屏幕印制(screen print)操作中对于错过焊膏的所有可能失效模式,现有的工艺控制是模板设计SD(Stencil Design)、定期地清洁模板、视觉检测VI(Visual Inspection)、设备预防性维护PM(Preventive Maintenance)和焊膏粘度检查。工艺工程师将目前所有的控制点包括在初始的MPI中,如模板设计研究、确定模板清洁、视觉检查的频率以及焊膏控制等。3.FMEA团队需要有针对性地按照MEA文件中的控制节点对现有的生产线进行审核,对目前的生产线的设置和其它问题进行综合考虑。如干燥盒的位置,审核小组建议该放在微间距布局设备(Fine-pitch Placementmachine)附近,以方便对湿度敏感的元器件进行处理。4.FMEA的后续活动在完成NPI的大致结构之后,可以进行FMEA的后续会议。会议的内容包括把现有的工艺控制和NPI大致结构的质量报告进行综合考虑,FMEA团队对RPN重新进行等级排序,每一个步骤首先考虑前三个主要缺陷,确定好推荐的方案、责任和目标完成日期。对于表面贴装工艺,首要的两个缺陷是焊球缺陷和tombstone缺陷,可将下面的解决方案推荐给工艺工程师:对于焊球缺陷,检查模板设计(stencildesign),检查回流轮廓(reflow profile)和回流预防性维护(PM)记录;检查屏幕印制精度以及拾取和放置(pick-and-place)机器的布局(placement)精度.对于墓石(tombstone)缺陷,检查屏幕印制精度以及拾取和放置(pick-and-place)机器的布局(placement)精度;检查回流方向;研究终端(termination)受污染的可能性。工艺工程师的研究报告表明,回流温度的急速上升是焊球缺陷的主要原因,终端(termination)受污染是墓石(tombstone)缺陷的可能原因,因此为下一个设计有效性验证测试结构建立了一个设计实验(DOE),设计实验表明一个供应商的元器件出现墓石(tombstone)缺陷的可能性较大,因此对供应商发出进一步调查的矫正要求。5.对于产品的设计、应用、环境材料以及生产组装工艺作出的任何更改,在相应的FMEA文件中都必须及时更新。FMEA更新会议在产品进行批量生产之前是一项日常的活动。批量生产阶段的FMEA管理作为一个工艺改进的历史性文件,FMEA被转移到生产现场以准备产品的发布。FMEA在生产阶段的主要作用是检查FMEA文件,以在大规模生产之前对每一个控制节点进行掌握,同时审查生产线的有效性,所有在NPI FMEA阶段未受质疑的项目都自然而然地保留到批量生产的现场。拾取和放置机器精度是工艺审核之后的一个主要考虑因素,设备部门必须验证布局机器的Cp/Cpk,同时进行培训以处理错误印制的电路板。FMEA团队需要密切监视第一次试生产,生产线的质量验证应该与此同时进行。在试生产之后,FMEA需要举行一个会议核查现有的质量控制与试生产的质量报告,主要解决每一个环节的前面三个问题。FMEA管理记录的是一个不断努力的过程和连续性的工艺改进,FMEA文件应该总是反映设计的最新状态,包括任何在生产过程开始后进行的更改。运用FMEA的意义 使用FMEA管理模式在早期确定项目中的风险,可以帮助电子设备制造商提高生产能力和效率,缩短产品的面市时间。此外通过这种模式也可使各类专家对生产工艺从各个角度进行检测,从而对生产过程进行改进。所推荐的方案应该是正确的矫正,产生的效益相当可观。为了避免缺陷的产生,需要对工艺和设计进行更改。使用统计学的方法对生产工艺进行研究,并不断反馈给合适的人员,确保工艺的不断改进并避免缺陷产生内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • 如何利用 either 和 option 进行函数式错误处理
  • spring boot 定制url匹配规则的方法
  • spring核心ioc和aop的理解
  • java实现将磁盘中所有空文件夹进行删除的代码
  • java防锁屏小程序代码实例
  • springboot使用druid数据源的配置方法
  • java命名规则详细总结
  • spring security跳转页面失败问题解决
  • spring boot报错:no session repository could be auto-configu
  • java 正则,object中两个方法的使用(详解)
  • 深入了解mybatis二级缓存
  • 求FMEA失效分析学习资料和实例
  • 结合身边的实例谈谈我们应当如何学习行道树精神.(50字左右)
  • 求实例可以来说明深层学习和浅层学习差异性,实例,最好加上出处.
  • 什么是案例
  • 努力学习的人并且成功了的实例,和不努力学习的人失败了的实例。
  • 结合你学习过的实例或日常生活中的例子谈谈对导数和微分的理解和认识
  • 急急急!!大学心理学 列举实例并结合学习的联结理论进行解释 简答!!
  • 通过“与情绪做朋友”这一章的学习,结合实例谈谈在日常生活中你是如何管理和调节自己的情绪的?
  • 我现在在学习java的三大框架,所有想找个实例来学习,谁有好的实例
  • 求 通过实例逐步学习excel vba的教程,就是那种通过一个个例子,由浅入深的学习编程的教程,或者
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全c#教程vbvb.netc 语言java编程delphijavaandroidiosswiftscala易语言汇编语言其它相关首页java如何利用 either 和 option 进行函数式错误处理spring boot 定制url匹配规则的方法spring核心ioc和aop的理解java实现将磁盘中所有空文件夹进行删除的代码java防锁屏小程序代码实例springboot使用druid数据源的配置方法java命名规则详细总结spring security跳转页面失败问题解决spring boot报错:no session repository could be auto-configujava 正则,object中两个方法的使用(详解)深入了解mybatis二级缓存java使double保留两位小数的多方java8 十大新特性详解java.net.socketexception: connjava写入文件的几种方法分享java环境变量的设置方法(图文教程java 十六进制与字符串的转换java list用法示例详解java中file类的使用方法javaweb实现文件上传下载功能实例java 字符串截取的三种方法(推荐java生成随机数的常用方法分析java语言实现简单ftp软件 ftp软件远程窗口java使用反射创建对象示例java代码书写规范汇总详解jpa多条件复杂sql动态分页查询功能spring boot + kotlin整合mybatis的方法教通过实例深入学习java的struts框架中的ogspring boot jpa 删除数据和事务管理的问java生成二维码并且给二维码添加logojava数据结构及算法实例:汉诺塔问题 han
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved