矩阵累积相乘 java_累积:轻松自定义Java收集器

矩阵累积相乘 java

Accumulative是针对Collector<T, A, R>的中间累积类型A提出的接口Collector<T, A, R>以使定义自定义Java Collector更加容易。

介绍

如果您曾经使用过Java Stream ,那么很可能会使用了一些Collector ,例如:

  • Collectors.toList
  • Collectors.toMap

但是你有没有使用过……

  1. 组成的 Collector
    • 它使用另一个 Collector作为参数,例如: Collectors.collectingAndThen
  2. 定制 Collector
    • 其功能在Collector.of明确指定。

这篇文章是关于custom Collector的。

集电极

让我们回想一下Collector合同的本质 (我的评论):

 /** * @param <T> (input) element type * @param <A> (intermediate) mutable accumulation type (container) * @param <R> (output) result type */  public interface Collector<T, A, R> { Supplier<A> supplier(); // create a container BiConsumer<A, T> accumulator(); // add to the container BinaryOperator<A> combiner(); // combine two containers Function<A, R> finisher(); // get the final result from the container Set<Characteristics> characteristics(); // irrelevant here  } 

上面的合同本质上是功能性的,这非常好! 这使我们可以使用任意累积类型( A )创建Collector ,例如:

  • AStringBuilderCollectors.joining
  • AOptionalBoxCollectors.reducing
  • Along[]Collectors.averagingLong

提案

在我提供任何理由之前,我将提出建议,因为它很简短。 该提议的完整源代码可以在GitHub上找到 。

累积接口

我建议将以下称为Accumulative (名称待讨论)的接口添加到JDK:

 public interface Accumulative<T, A extends Accumulative<T, A, R>, R> { void accumulate(T t); // target for Collector.accumulator() A combine(A other); // target for Collector.combiner() R finish(); // target for Collector.finisher()  } 

Collector相反,此接口本质上是面向对象的 ,实现该接口的类必须表示某种可变状态

过载收集器

具有Accumulative ,我们可以添加以下Collector.of重载:

 public static <T, A extends Accumulative<T, A, R>, R> Collector<T, ?, R> of( Supplier<A> supplier, Collector.Characteristics... characteristics) { return Collector.of(supplier, A::accumulate, A::combine, A::finish, characteristics);  } 

普通开发者故事

在本部分中,我将展示该建议会对普通开发人员产生怎样的影响,因为他们只了解 Collector API的基础知识 。 如果您精通此API,请在继续阅读之前尽力想象您不知道。

让我们重用我最近的文章中的示例(进一步简化)。 假设我们有一个Stream

 interface IssueWiseText { int issueLength(); int textLength();  } 

并且我们需要计算问题覆盖率

总发行时长
─────────────
总文字长度

此要求转换为以下签名:

 Collector<IssueWiseText, ?, Double> toIssueCoverage(); 

一般的开发人员可能会决定使用自定义累积类型A来解决此问题(不过其他解决方案也是可能的 )。 假设开发人员将其命名为CoverageContainer这样:

  • TIssueWiseText
  • ACoverageContainer
  • RDouble

下面,我将展示这样的开发人员如何实现CoverageContainer结构

无累积结构

注意 :本节很长,目的是说明该过程对于没有使用Collector的开发人员可能有多复杂 如果您已经意识到这一点则可以跳过它

如果没有Accumulative ,则开发人员将查看Collector.of ,并看到四个主要参数:

  1. Supplier<A> supplier
  2. BiConsumer<A, T> accumulator
  3. BinaryOperator<A> combiner
  4. Function<A, R> finisher

要处理Supplier <A> supplier ,开发人员应:

  1. Supplier<A>中用心理替代A获得Supplier<CoverageContainer>
  2. 在精神上将签名解析为CoverageContainer get ()
  3. 回想一下JavaDoc for Collector.supplier()
  4. 第四种调用方法的引用 ( 对构造函数的引用
  5. 意识到supplier = CoverageContainer::new

要处理BiConsumer <A, T> accumulator ,开发人员应:

  1. BiConsumer<CoverageContainer, IssueWiseText>
  2. void accept (CoverageContainer a, IssueWiseText t)
  3. 在精神上将签名转换为一种实例方法
    void accumulate(IssueWiseText t)
  4. 第三种调用方法的引用 ( 引用特定类型的任意对象的实例方法
  5. 意识到accumulator = CoverageContainer::accumulate

处理BinaryOperator <A> combiner

  1. BinaryOperator<CoverageContainer>
  2. CoverageContainer apply (CoverageContainer a, CoverageContainer b)
  3. CoverageContainer combine(CoverageContainer other)
  4. combiner = CoverageContainer::combine

要处理Function <A, R> finisher

  1. Function<CoverageContainer, Double>
  2. Double apply (CoverageContainer a)
  3. double issueCoverage()
  4. finisher = CoverageContainer::issueCoverage

这个漫长的过程导致:

 class CoverageContainer { void accumulate(IssueWiseText t) { } CoverageContainer combine(CoverageContainer other) { } double issueCoverage() { }  } 

开发人员可以定义toIssueCoverage() (必须以正确的顺序提供参数):

 Collector<IssueWiseText, ?, Double> toIssueCoverage() { return Collector.of( CoverageContainer:: new , CoverageContainer::accumulate, CoverageContainer::combine, CoverageContainer::finish );  } 

累积结构

现在, 使用 Accumulative ,开发人员将查看新的Collector.of重载,并且将仅看到一个主要参数:

  1. Supplier<A> supplier

和一个有界类型参数 :

  • A extends Accumulative<T, A, R>

因此,开发人员将自然而然地开始- 实施 Accumulative<T, A, R>第一次和最后一次解析TAR

 class CoverageContainer implements Accumulative<IssueWiseText, CoverageContainer, Double> {  } 

此时,一个不错的IDE会抱怨该类必须实现所有抽象方法。 而且,这是最美丽的部分 ,它将提供快速修复。 在IntelliJ中,您单击“ Alt + Enter”→“实施方法”,然后…就完成了!

 class CoverageContainer implements Accumulative<IssueWiseText, CoverageContainer, Double> { @Override public void accumulate(IssueWiseText issueWiseText) {     } @Override public CoverageContainer combine(CoverageContainer other) { return null ; } @Override public Double finish() { return null ; }  } 

因此,您不必弄乱类型,手动编写任何内容或命名任何内容!

哦,是的-您仍然需要定义toIssueCoverage() ,但是现在很简单:

 Collector<IssueWiseText, ?, Double> toIssueCoverage() { return Collector.of(CoverageContainer:: new );  } 

那不是很好吗?

实作

这里的实现无关紧要,因为这两种情况( diff )几乎相同。

基本原理

程序太复杂

我希望我已经演示了如何定义自定义Collector是一个挑战。 我必须说,即使我总是不愿意定义一个。 但是,我也感觉到-有了Accumulative ,这种不情愿就消失了,因为程序将缩小为两个步骤:

  1. 实现Accumulative<T, A, R>
  2. 调用Collector.of(YourContainer::new)

推动实施

JetBrains创造了“ 发展动力 ”,我想将其转变为“实施动力”。

由于Collector是一个简单的功能的设备中,这通常是没有意义的(据我可以告诉)来实现它(也有例外 )。 但是,通过Google搜索“实施收集器” ,可以看到(约5000个结果)人们正在这样做。

这很自然,因为要在Java中创建“自定义” TYPE ,通常会扩展/实现TYPE 。 实际上,即使是经验丰富的开发人员(例如Java冠军Tomasz Nurkiewicz )也可以做到这一点。

综上所述,人们感到有实现动力 ,但在这种情况下,JDK没有为他们提供实现的任何东西。 Accumulative可以填补这一空白……

相关例子

最后,我搜索了一些易于实现Accumulative示例。

在OpenJDK(尽管这不是目标位置)中,我发现了两个:

  1. Collectors.reducing ( diff )
  2. Collectors.teeing ( diff )

对堆栈溢出,虽然,我发现大量的: 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 。

我还发现了一些基于数组的示例,可以将其重构Accumulative以获得更好的可读性: a , b , c 。

命名

Accumulative不是最好的名字,主要是因为它是一个形容词 。 但是,我选择它是因为:

  • 我希望名称以A开头(如<T, A, R> ),
  • 我最好的候选人( Accumulator )已经被BiConsumer<A, T> accumulator()
  • AccumulativeContainer似乎太长。

在OpenJDK中, A称为:

  • 可变结果容器
  • 累积类型
  • 容器

提示以下替代方法:

  • AccumulatingBox
  • AccumulationState
  • Collector.Container
  • MutableResultContainer

当然,如果这个想法被接受,这个名字将通过“传统”的名字

摘要

在本文中,我建议向JDK添加Accumulative接口和新的Collector.of重载。 有了它们,开发人员将不再费劲地创建自定义Collector 。 取而代之的是,它只是变成了“执行合同”和“引用构造函数”。

换句话说,该提案旨在降低进入“定制Collector世界的门槛

附录

下面的可选阅读。

解决方案示例:JDK 12+

在JDK 12+中,由于Collectors.teeing ( JDK-8209685 ),我们将toIssueCoverage()定义为组合的Collector

static Collector<IssueWiseText, ?, Double> toIssueCoverage() {return Collectors.teeing(Collectors.summingInt(IssueWiseText::issueLength),Collectors.summingInt(IssueWiseText::textLength),(totalIssueLength, totalTextLength) -> (double) totalIssueLength / totalTextLength);
}

上面的内容很简洁,但是对于Collector API新手来说,可能很难遵循。

示例解决方案:JDK方法

另外, toIssueCoverage()可以定义为:

static Collector<IssueWiseText, ?, Double> toIssueCoverage() {return Collector.of(() -> new int[2],(a, t) -> { a[0] += t.issueLength(); a[1] += t.textLength(); },(a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },a -> (double) a[0] / a[1]);
}

我称其为“ JDK方式”,因为某些Collector的实现与OpenJDK中的实现类似(例如Collector.averagingInt )。

但是,尽管这样的简洁代码可能适用于OpenJDK,但由于可读性高(这很低,我称之为cryptic ),因此它肯定适合业务逻辑。

翻译自: https://www.javacodegeeks.com/2019/02/accumulative-custom-java-collectors.html

矩阵累积相乘 java

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

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

相关文章

java socket 传输压缩文件_java基于socket传输zip文件功能示例

本文实例讲述了java基于socket传输zip文件的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;服务器端程序&#xff1a;import java.io.*;import java.net.*;import java.io.BufferedInputStream;public class SocketServer {ServerSocket ssnull;Socket snull;Dat…

css的学习

文章目录内联样式内部样式外部样式CSS语法格式选择器基本选择器ID 选择器元素选择器类选择器不带标签名带标签名通用选择器并集选择器选择器的优先级扩展选择器组合选择器属性选择器伪类选择器伪元素选择器css 是 Cascading Style Sheets&#xff0c;层叠样式表。 层叠含义是多…

java throws catch_java异常处理throws throw try-catch实例

java异常处理throws throw try-catch实例。throw用于方法中&#xff0c;我们可以预见的错误。比如&#xff1a;if(age<0){Exception e new Exception();//创建异常对象throw e;//抛出异常}在java代码中如果发生异常的话&#xff0c;jvm会抛出异常对象&#xff0c;导致程序代…

java 开发人员工具_每个Java开发人员都应该知道的10个基本工具

java 开发人员工具大家好&#xff0c;我们已经到了2019年的第二个月&#xff0c;我相信你们所有人都已经制定了关于2019年学习以及如何实现这些目标的目标。 我一直在撰写一系列文章&#xff0c;为您提供一些知识&#xff0c;使您可以学习和改进以成为2019年更好的全方位开发人…

SpringBoot2.x+mybatis plus3.x集成Activit7版本

文/朱季谦 在Activiti6版本当中&#xff0c;若要集成到Springboot里&#xff0c;需要写一些额外的配置类&#xff0c;我曾经在Activiti工作流框架学习笔记&#xff08;二&#xff09;之springboot2.0整合工作流Activiti6.0一文当中总结过相关配置过程&#xff0c;感兴趣的同学…

camel apache_Apache Camel 3的工作终于开始了

camel apache我们正在开始Apache Camel 3的工作。 我们正在多方面努力改善骆驼并引入新功能。 Guillaume Nodet实际上是在10月初开始了第一项工作&#xff0c;他通过清理代码库&#xff0c;删除不推荐使用的代码和组件&#xff0c;改进了路由引擎和核心中的其他内部组件开始了…

(前端开发)表格中的行全选、全不选、反选以及数据行背景色变换的示例代码

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>表格数据行全选/全不选/反选的示例</title><style>table {border: 1px solid;width: 500px;margin-left: 30%;}th, td {text-align: cente…

future java 多线程_Java多线程之Future与FutureTask

一&#xff1a;Future在使用实现Callable创建线程时&#xff0c;call()方法是有返回值的。那么&#xff0c;我们在编程时用什么来代表这个 线程执行后才能返回的未来结果 呢&#xff1f;那就是 Future类型。顾名思义&#xff0c;Future——未来值&#xff0c;我们用这个未来值来…

switch字符串jdk_从JDK 12删除原始字符串文字

switch字符串jdk已经提出从JDK 12中删除原始字符串文字&#xff08;预览&#xff09; &#xff08;它将在12月13日进入Rampdown第一阶段 &#xff09;。 Brian Goetz撰写了删除此预览功能的动机的详细说明 &#xff08; JEP 326 &#xff09;。 在Java subreddit上也对此进行了…

win7旗舰版安装不了python_怎样在Win7 64位旗舰版安装Python+Eclipse开发环境

自从上周抛弃了WinXP转而安装了Win7&#xff0c;64位后&#xff0c;尝试安装PythonEclipse遇到了一点小问题。现在已经解决&#xff0c;将安装顺序记录如下&#xff0c;供参考。Setp1&#xff0c;到ORACLE网站下载64位的JDK。http://www.oracle.com/technetwork/java/javase/do…

MacOS下的取色器/拾色器推荐

文章目录ColorSnapper2ColorSlurp 不错&#xff0c;App Store 可以下载SipChromaColor PickerPixeur&#xff08;推荐&#xff09;操作说明ColorSnapper2 ColorSlurp 不错&#xff0c;App Store 可以下载 Sip Chroma Color Picker Pixeur&#xff08;推荐&#xff09; 体…

查看oracle会话和进程_带有Oracle Digital Assistant和Fn Project的会话式UI

查看oracle会话和进程在这里和那里&#xff0c;我们看到了无数的预测&#xff0c;很快聊天机器人将在用户与其系统之间的通信中扮演关键角色。 我没有水晶球&#xff0c;也不想等待这个“很快”&#xff0c;所以我决定现在就使这些预言成真&#xff0c;看看它是什么样。 我正在…

设置 input元素placeholder的字体颜色

placeholder 属性提供可描述输入字段预期值的提示信息&#xff08;hint&#xff09;。 该提示会在输入字段为空时显示&#xff0c;并会在字段获得焦点时消失。 placeholder 属性适用于以下的 <input> 类型&#xff1a;text, search, url, telephone, email 以及 passwo…

网页益智游戏怎么制作_休息一下,或者:如何使用Java 12制作出色的益智游戏...

网页益智游戏怎么制作Java 12以实验形式提供了switch表达式以及switch和break语句的新形式。 对于可能很少用到的构造&#xff0c;有大量的新语法和语义-当然&#xff0c;对于那些困惑者和认证考试问题的作者来说&#xff0c;这是一件了不起的礼物。 如果您喜欢Java拼图游戏&am…

java aes 解密 文件_Java AES文件加解密

转自&#xff1a;http://www.webtag123.com/java/4049.htmlAESUtils.javapackage demo.security;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.security.Key;imp…

JavaScript(JS)的习惯写法总结

//取整 parseInt(a,10); //Before Math.floor(a); //Before a>>0; //Before ~~a; //After a|0; //After//四舍五入 Math.round(a); //Before a.5|0; //After//内置值 undefined; //Before void 0; //After, 快 0[0]; //After, 略慢//内置值 Infinity; 1/0;//布尔值短写法…

java模拟连接超时_Java:使用Toxiproxy模拟各种连接问题

java模拟连接超时用Toxiproxy和Java的HttpURLConnection模拟各种连接问题&#xff0c;以查看产生了什么样的错误&#xff1a;连接超时vs.读取超时vs.连接被拒绝…。 结果&#xff1a; 系统&#xff1a;openjdk 11.0.1 2018-10-16 (.setConnectTimeout 1) > java.net.Socke…

java中的僵死进程_Java中线程间怎么通讯?什么叫僵死线程?

《尸家保镖》 《猛鬼出千》 《不死心灵》 《大家发财》 《灵幻少女》 《九天玄女》 《僵尸至尊》 《湘西尸王》 《尸前想后》 《魔高一丈》 《一世好命》 《妖兽尸王》 《人蝎大战》 《星际钝胎》 《艳女还魂》 《邪完再邪》 《艳鬼山坟》 《尸破今天阳光很好&#xff0c;坐在窗…

正则表达式中的分组的匹配次数的理解

正则表达式&#xff1a;/((\d){1,6})/ 这个正则表达式可以匹配任意数量的数字。 限定符 指的是前面的子表达式 (\d){1,6} 可以出现 1 次或者多次&#xff0c;所以如果是贪婪匹配&#xff0c;每次迭代匹配的数字个数可以超过 6 个&#xff08;即 ≥1&#xff09;&#xff1b;如…

aws使用技巧_AWS:避免那些“神圣的法案”时刻的一些技巧

aws使用技巧云非常棒&#xff1a;几乎100&#xff05;的可用性&#xff0c;接近零的维护&#xff0c;按需付费&#xff0c;最重要的是&#xff0c;它具有无限的可扩展性。 但是最后两个很容易把你咬回去&#xff0c;把那令人敬畏的事情变成一场噩梦。 偶尔您会看到类似的故事…