高频变压器_变压器图案

高频变压器

Transformer模式是Java(以及可能仅具有使用场所差异和不变参数类型的其他OO语言)的设计模式,可帮助子类型层次结构内的对象将自己流畅地转换为任何类型的对象。

语境

我一直在关注与Jim Laskey发行的JDK-8203703有关的OpenJDK线程( 9月18-21日 , 11月12-13日, 11月13-30日, 12月3-4日 ),然后我想到了一个主意。 让我回顾一下讨论的相关部分。

String.transform的建议

根据JDK-8203703的提案可归结为以下新增内容:

public final class String implements /*...*/ CharSequence {// ...public <R> R transform(Function<? super String, ? extends R> f) {return f.apply(this);}// ...
}

如您所见,此方法本身仅调用给定的Function即可。 但是,它对于链接实用程序方法非常有用,例如Apache Commons的 StringUtils中的方法:

String result = string.toLowerCase().transform(StringUtils::stripAccents).transform(StringUtils::capitalize);

通常,我们必须写:

String result = StringUtils.capitalize(StringUtils.stripAccents(string.toLowerCase()));

考虑CharSequence.transform

在某个时候,艾伦·贝特曼(Alan Bateman) 提出了 transform CharSequence中的transform定义为以下问题:

<R> R transform(Function<? super CharSequence, ? extends R> f)

这将具有能够在任何CharSequence上应用基于CharSequence的实用程序方法(例如StringUtils.isNumeric )的好处,例如:

boolean isNumeric = charSequence.transform(s -> StringUtils.defaultIfBlank('0')).transform(StringUtils::isNumeric);

但是,正如RémiForax 指出的那样 ,此签名的问题在于:

  • 如果它是由String 继承的:大多数实用程序方法都将String作为参数–这样的方法将不起作用(例如StringUtils :: capitalize ),
  • 如果它被String 覆盖 :由于以下原因,无法进行有用的覆盖:
    • Function<? super String, R>

结果, CharSequence.transform的主题已被删除。

问题

综上所述,问题在于能够进行转换

  • 一个CharSequence ,使用Function即需要CharSequenceObject? super CharSequence ),
  • 一个String ,使用接受String或其任何父类型( ? super String )的Function

当我在这里查看这些下 限时 ,我意识到我已经看到了这种问题(参见Filterer Pattern )。

因此,这个问题归结为:如何协变地指定Function 界。

Java不支持逆变参数类型 ,并且其语法也不提供在单个声明中协变( ? extends )指定逆变( ? super )绑定的方法。 然而,有可能做到这一点在两个分开的宣言,通过中间辅助类型的装置。

假设我们要为泛型Function<? super T, ? extends R> Function<? super T, ? extends R> Function<? super T, ? extends R> ,我们需要:

  • 将上面的Function参数移动到参数为T辅助接口中
  • 将此辅助接口与上限 ( ? extends T )一起用作返回类型。

变压器接口

我定义了这样的帮助程序接口(我称之为Transformer ),如下所示:

@FunctionalInterface
interface Transformer<T> {<R> R by(Function<? super T, ? extends R> f);
}

可转换的接口

定义了Transformer ,我们可以定义以下称为Transformable基本接口:

interface Transformable {Transformer<?> transformed();
}

该接口本身并不能做很多事情,但我将其视为以下方面的规范

  • 子类型实现器 :提醒他们使用适当的上限覆盖已transformed方法,并加以实现,
  • 子类型用户 :提醒他们可以调用transformed().by(f)

总结起来,这对( TransformerTransformable )让我们替换:

  • obj.transform(function)
  • 使用: obj.transformed().by(function)

样例实施

回到String之前,让我们看看实现这两个接口有多么容易:

class Sample implements Transformable {@Overridepublic Transformer<Sample> transformed() {return this::transform; // method reference}private <R> R transform(Function<? super Sample, ? extends R> f) {return f.apply(this);}
}

如您所见,所需要的只是对transform的方法引用 。

transform方法被设为私有,因此当子类型定义自己的(适当地, 下界 ) transform时,它们之间不会发生冲突。

上下文中的解决方案

上下文中的实现

它如何应用于CharSequenceString ? 首先,我们将CharSequence扩展为Transformable

public interface CharSequence extends Transformable {// ...@OverrideTransformer<? extends CharSequence> transformed();// ...
}

然后,我们transformedString实现transformed ,返回对public transform方法( 在JDK 12中添加 )的方法引用:

public final class String implements /*...*/ CharSequence {// ...@Overridepublic Transformer<String> transformed() {return this::transform;}// ...
}

请注意,我们对transformed的返回类型进行了协变更改: Transformer<? extends CharSequence> Transformer<? extends CharSequence>Transformer<String>

相容性风险

我认为添加CharSequence.transformed的兼容性风险很小。 仅对于那些已经具有无参数transformed方法的CharSequence子类,这可能会破坏向后兼容性(这似乎不太可能)。

上下文中的用法

对于使用String不会改变,因为有呼吁没有一点transformed().by()transform()

但是,通用CharSequence的用法将需要诉诸transformed().by()因为它可能有许多实现,因此transform方法必须是private

boolean isNumeric = charSequence.transformed().by(s -> StringUtils.defaultIfBlank('0')).transformed().by(StringUtils::isNumeric);

性能

如果您不熟悉JVM (最常表示HotSpot )及其JIT编译器的工作方式,那么您可能会怀疑这种额外对象的明显创建( Transformer in transformed )是否不会影响性能。

幸运的是,由于进行了转义分析 *和标量替换 ,因此该对象永远不会在堆上分配。 答案是:不,不会。

* 此Wikipedia条目包含错误的陈述:“ 因此,编译器可以安全地在堆栈上分配两个对象。 ”正如 AlekseyShipilёv解释的那样 ,Java不会在堆栈上分配整个对象。

基准测试

如果您需要证明,这里有一些基准(使用AlekseyShipilёv出色的JMH基准线束 )。 因为我不能(容易),添加必要的方法,以String ,我创建了一个简单的包装过String ,并实现了在它之上的标杆。

基准测试toLowerCase()操作:

  • 在两个字符串上:
    1. "no change" (无操作)
    2. "Some Change"
  • 使用三种通话类型:
    1. 直接(基准)
    2. transform()
    3. transformed().by()

您可以在GitHub gist中找到此基准测试的完整源代码。

结果如下(在Oracle JDK 8上运行,耗时50分钟):

Benchmark                            (string)  Mode  Cnt   Score   Error  UnitsTransformerBenchmark.baseline       no change  avgt   25  22,215 ± 0,054  ns/op
TransformerBenchmark.transform      no change  avgt   25  22,540 ± 0,039  ns/op
TransformerBenchmark.transformed    no change  avgt   25  22,565 ± 0,059  ns/opTransformerBenchmark.baseline     Some Change  avgt   25  63,122 ± 0,541  ns/op
TransformerBenchmark.transform    Some Change  avgt   25  63,405 ± 0,196  ns/op
TransformerBenchmark.transformed  Some Change  avgt   25  62,930 ± 0,209  ns/op

如您所见,对于这两个字符串,这三种调用类型之间没有性能差异。

摘要

我意识到, Transformable可能过于“奢侈”,以致于无法真正将其纳入JDK。 实际上,即使仅由CharSequenceString返回的Transformer也不值得。 这是因为对CharSequence的一元运算似乎并不常见(例如StringUtils仅包含少数几个)。

但是,我发现“ Transformer和“ Transformable的基本概念很诱人。 因此,我希望您喜欢阅读,并且在某些情况下会发现它很有用

翻译自: https://www.javacodegeeks.com/2019/02/transformer-pattern.html

高频变压器

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

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

相关文章

linux文件 run.man,【Linux】linux经常使用基本命令

Linux中很多经常使用命令是必须掌握的&#xff0c;这里将我学linux入门时学的一些经常使用的基本命令分享给大家一下&#xff0c;希望能够帮助你们。这个是我将鸟哥书上的进行了一下整理的&#xff0c;希望不要涉及到版权问题。1、显示日期的指令&#xff1a; date2、显示日历的…

guid会重复吗_知网查重会查重表格吗

知网查重会查重表格吗&#xff1f;答案是肯定的。如果出现知网查重表格重复很高&#xff0c;那么我们一样是会进行避免查重的&#xff0c;通常表格在查重后会在报告中展示&#xff0c;如果出现重复会提示大家&#xff0c;我们只需要根据这个提示进行修改降低表格查重率即可。那…

stripe pay_J2Pay –简介

stripe pay介绍 J2Pay是用于Java的开源多网关支付库&#xff08;由tranxactive提供&#xff09;。 该库的主要目的是为多个网关同时提供简单而通用的请求/响应&#xff0c;它也排除了网关文档的阅读。 如果您尝试在网关上工作&#xff0c;则不必阅读文档&#xff0c;因为该库具…

windows远程桌面_如何使用Windows远程桌面连接Ubuntu 干货

近期网盾科技给大家分享了一些教程类的干货&#xff0c;有很多小伙伴都收藏了网盾科技的文章&#xff0c;能对大家有帮助就好。今天网盾科技再给小伙伴们讲解一下如何使用Windows远程桌面连接Ubuntu&#xff0c;干货收藏&#xff01; Windows连接已有界面的Linux 看了许多教程都…

android 单元测试 多线程,单元测试多线程Android RxJava

您可以编写自己的ThreadFactoryThreadFactory custom new CustomThreadFactory();ExecutorService executorService Executors.newCachedThreadPool(custom); //or use newSingleThreadExecutor(..)Scheduler customScheduler Schedulers.from(executorService); 现在你可以…

Servlet中获取文件在服务器主机的真实路径

package priv.lwx.javaex.servlet_demo.web.servletcontext; /*** 获取文件在服务器主机的真实路径** author liaowenxiong* date 2022/1/12 15:34*/import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet…

wxpay-api:pay_J2Pay – API响应

wxpay-api:pay介绍 该库中的神奇之处在于&#xff0c;无论网关是什么&#xff0c;其响应都是唯一的。 了解API响应后&#xff0c;您便可以轻松地将此响应用于进一步的交易&#xff0c;例如退款&#xff0c;作废或重新开票。 首先&#xff0c;在开始阅读时&#xff0c;所有响应…

Android设置toolbar高度,Android基础知识之 Toolbar 的使用

Toolbar是Android5.0推出的,用来替代ActionBar的控件.可以高度的自定义,使用灵活.官方的ToolBar是必须在5.0以上的系统才能使用,如果需要在低版本中使用.需要使用support v7包中的Toolbar.下一是官网的Toolbar的介绍:Toolbarextends ViewGroupjava.lang.Object↳ android.view.…

delphi 停电文本数据丢失_概述DCS系统正确停电和上电的步骤

欢迎关注“热控圈 ” ID&#xff1a;rekongquan传播热控知识&#xff0c;分享技术精华&#xff01;如何由入门到精通学会西门子PLC系统&#xff1f;扫码关注“电力工程学”&#xff0c;系列视频正在播出&#xff01;在因大修或者其他原因需要对DCS进行断电维护时&#xff0c;我…

获取文件的MIME类型

package priv.lwx.javaex.servlet_demo.web.servletcontext; /*** 获取MIME类型** author liaowenxiong* date 2022/1/12 15:34*/import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.File; import java.io.IOException;…

jcmd_jcmd,大约JDK 11

jcmdNicolasFrnkel最近在博客文章“ 行业工具OpenJDK 11 ”中发布了与OpenJDK 11一起提供的命令行工具的调查。 在那篇文章中&#xff0c;他简要总结了工具jps &#xff08;一个JVM进程状态工具 &#xff09;&#xff0c; jinfo &#xff08;一个JVM配置详细信息 &#xff09;&…

vscode 运行vue_Vue初体验

Vue的引入要使用 Vue&#xff0c;我们可以直接在 Vue.js 的官网直接下载 vue.min.js 文件&#xff0c;然后在 HTML 页面中通过 <script> 标签来引入这个文件。下载地址为&#xff1a;https://vuejs.org/js/vue.min.js。引入格式如下所示&#xff0c;其中 path 是文件所在…

android图标随着进度条动画,Android开发之ProgressBar字体随着进度条的加载而滚动...

在网上翻阅了很多关于ProgressBar滚动效果&#xff0c;但是始终没有找到适合项目中的这种效果&#xff0c;故自己写这篇文章&#xff0c;记录一下写作过程&#xff0c;给大家做一个参考。先看下最终效果效果图我这里用的是LICEcap软件录制的gif图&#xff0c;效果有点掉帧&…

spark ui_Spark UI的见解

spark ui作为apache-spark-job解剖的后续文章&#xff0c;我将分享您如何使用Spark UI进行作业调整。 我将继续使用先前文章中使用的相同示例&#xff0c;新的spark应用程序将在以下方面完成工作 –阅读纽约市停车票 –通过“板ID”进行汇总并计算违规日期 –保存结果 此代…

Android布局加载慢,Android布局优化(四)X2C — 提升布局加载速度200%

系列文章前言在Android布局优化(一)从布局加载原理说起中我们说到了布局加载的两大性能瓶颈&#xff0c;通过IO操作将XML加载到内存中并进行解析和通过反射创建View。这里介绍一种避免运行时通过IO操作读取布局文件的“黑科技”—X2C。个人认为这个技术在实际项目中使用可能会需…

api 获取网络使用情况_您的API是什么情况?

api 获取网络使用情况免责声明&#xff1a;在纯REST中&#xff0c;API是不透明的&#xff0c;URL应该是对先前请求的响应中作为链接发送的内容。 但是&#xff0c;我不是在讲纯REST&#xff0c;而是在讲更实用的API&#xff0c;其中涉及REST的一些概念以及通用的API最佳实践。 …

判断字符串是不是application/x-www-form-urlencoded字符串(URL编码格式的字符串)

import java.util.BitSet;/*** 判断一个字符串是不是URL编码字符串的工具类&#xff0c;即判断字符串是不是application/x-www-form-urlencoded字符串** author liaowenxiong* date 2022/1/14 11:32*/public class URLEncodeUtils {private static BitSet bitSet;static {bitSe…

数据查询和业务流分开_传统数仓和大数据数仓的区别是什么?

概念与容器为什么先说这个&#xff0c;其实很简单&#xff1a;因为绝大多数人都把这两个概念混为一谈。然后就会出现各种各样的问题&#xff1a;oracle不是数据库么&#xff0c;怎么又是数据仓库&#xff1f;Hive不是数据仓库么&#xff1f;怎么又是数据库&#xff1f;数据仓库…

android 多语言不起作用,Android本地化语言环境不起作用,所有区域代码都存在问题...

我需要将除瑞士之类的子语言环境添加到我的应用程序中,而不是普通的德语.我找到的德语资源文件夹的语言环境扩展名为de.所以我的文件夹名为“values-de”.这很好.然后我添加了“values-de_CH”并继续收到错误“无效的资源目录名称”.我也试过“values-de_rCH”和“values-de_ch…

aws 性能_AWS上的应用程序自动扩展–选项和对性能的影响

aws 性能至关重要的是扩展软件应用程序&#xff0c;以避免由于网站的客户群或需要处理大型数据集的应用程序等导致的工作负载增加而导致性能瓶颈的情况。云服务提供商通常是访问其他应用程序的最佳方法随需应变的资源&#xff0c;可根据应用程序的负载变化来放大或缩小。 1.什…