返回顶部
首页 > 资讯 > 精选 >Clojure与Java对比实例分析
  • 315
分享到

Clojure与Java对比实例分析

2023-07-02 08:07:18 315人浏览 安东尼
摘要

这篇文章主要介绍“Clojure与Java对比实例分析”,在日常操作中,相信很多人在Clojure与Java对比实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Clojure与Java对比实例分析”的疑

这篇文章主要介绍“Clojure与Java对比实例分析”,在日常操作中,相信很多人在Clojure与Java对比实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Clojure与Java对比实例分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    问题所在

    我一直在写一个代理,接收javax.servlet.Http.httpservletRequest 并通过Apache HttpClientorg.apache.http.client.methods.HttpUriRequest,然后从org.apache.http.HttpResponsejavax.servlet.http.HttpServletResponse,尤其是关于(一个子集)头的响应。

    这是一件痛苦的事,因为每个人都有自己的头表示和使用headers的API:

    // javax.servlet.http.HttpServletRequest:Enumeration<String> getHeaderNames();Enumeration<String> getHeaders(String name);// org.apache.http.client.methods.RequestBuilder:RequestBuilder addHeader(String name, String value);//-------------// javax.servlet.http.HttpServletResponse:void addHeader(String name, String value);// org.apache.http.HttpResponse:Header[] getAllHeaders();// Header:String getName();String getValue();

    这里,枚举和数组是通用的数据结构,但头和请求对getHeaderNamesgetHeaders的拆分需要特定的代码。

    因此,我必须编写translation函数,如:

    def copyRequestHeaders(HttpServletRequest source, RequestBuilder target) {    source.getHeaderNames().each { String hdr ->        source.getHeaders(hdr).each { String val ->            if (undesirable(hdr)) return            target.addHeader(hdr, val)        }    }}

    static void copyResponseHeaders(HttpResponse source, HttpServletResponse target) {    source.allHeaders.each { Header hdr ->        if (target.getHeader(hdr.name.toLowerCase()) == hdr.value) return // avoid duplicates        if (undesirable(hdr.name)) return        target.addHeader(hdr.name, hdr.value)    }}

    理想情况下,我希望能够像target这样做target.request.headers = omiTKEys(undesirable, source.request.headers)。但这是不可能的,我必须从一组类型映射到另一组类型。这里的主要问题是servlet请求被拆分为getHeaderNamesgetHeaders,而不是返回例如Map<String,String[]>,还有RequestBuilder,它有addHeader,但无法一次添加所有头(除非我们首先将它们包装在其域类中,即Header中)。

    (可以说,我可以找到一个更好的例子来说明这一点。在这里,我们仍然主要(但不总是)使用枚举、字符串、数组等基元/泛型类型,而不是嵌套的自定义类型层次结构。)

    Clojure解决方案

    在Clojure中,请求只是一个映射,标题很可能是列表的映射。即使这两个库(服务器、客户端)在密钥名称或数据结构上不一致,也没有“api”可学习-您只需使用相同的旧已知函数从一个数据结构转换到另一个数据结构,这是您在每个Clojure项目WEB、数据或任何其他领域中所做的事情。唯一改变的是地图中关键点的名称。

    注意:如果您不知道Clojure,那么一些示例可能很难阅读,例如assocreduce-kv (key-value)函数以及偶尔的单字母名称。请记住,Clojure程序员反复使用相同的100个函数,并且非常熟悉它们。与其他一些语言相反,Clojure有意识地选择为有经验的开发人员进行优化。这对我来说很好。

    案例1:相同的Keys

    最简单的情况是,使用相同的key,我们只想选择一个子集:

    (assoc  target-request  :headers  (select-keys (:headers source-request) [:pragma :content-type ...]))

    唯一区分大小写的部分是keys。在Java中,您不能像我们在这里使用通用选择键那样一次选择所有所需的keys,您需要通过类特定的getHeaders(name)逐个选择它们。

    案例2:不同的Key名,相同的数据结构

    (assoc  target-request  :headersX  (clojure.set/rename-keys    (select-keys (:headersY source-request) [:Pragma :ContentType ...])    {:Pragma :pragma, :ContentType :content-type}))

    如果需要更复杂的key转换,我们可以使用例如map:

    (defn transfORM-key [k] ...)(let [hdrs (->> (select-keys headers [:a])                (map (fn [[k v]] [(transform-key k) v]))                (into {}))]    (assoc target-request :headersX hdrs))

    关键是,在从一个数据结构映射到另一个数据结构的过程中,我们仍然使用我们所知道和喜爱的相同功能,唯一针对具体情况的部分是键和键转换函数。我们可以简单地映射头映射,这在HttpServletRequest的头上是不可能的。

    案例3:不同的数据结构

    headers作为name-value对列表(可能有重复的名称)进入name-value映射:

    (def headers-in [["pragma" "no-cache"] ["accept" "X"] ["accept" "Y"]])(->> headers-in     (group-by first)     (reduce-kv       (fn [m k vs]         (assoc           m           k           (map second vs)))       {})); => {"pragma" ("no-cache"), "accept" ("X" "Y")}

    案例4:Reality

    实际上,我们可能会使用Ring作为服务器,并将Clojure包装器clj-http用于Apache HttpClient。

    请求如下所示:

    {:headers {"accept" "x,y", "pragma" "no-cache"}}

    (我们可以添加ring-request-headers-middleware,将连接的值转换为单个值的列表。)

    Clj-http遵循Ring规范,因此支持相同的格式,但更为宽松:

    clj http对头的处理比ring规范指定的要宽松一些。

    clj http允许任何大小写的字符串或关键字,而不是强制所有请求头都是小写字符串。关键字将转换为它们的规范表示形式,因此:content-md5标头将作为“content-md5”发送到服务器。但是,请求头中的字符串键将被发送到服务器,其大小写保持不变。

    响应标题可以作为任何大小写的关键字或字符串读取。如果服务器以“Date”标头响应,则可以访问该标头的值,如:Date、“Date”、“Date”等。

    这就是上面第1种情况。

    Java Vs Clojure

    我想指出的一点是,Clojure在解决两个问题方面更为有效:数据选择和转换,这要归功于对其使用通用数据结构和函数。

    选择

    在Clojure中,通过选择另一个映射的子集来创建映射非常简单(assoc将键与值关联,select keys返回映射):

    (assoc  request  :headers  (select-keys    (:headers other-request)    [:pragma ...]))

    使用典型的Java数据类(还记得DTOs吗?)您需要逐个获取和设置各个属性。即使我们使用Groovy便利:

    new Person(  firstName: employee.firstName,  lastName: employee.lastName,  ...)

    这里的重点并不是键入的数量,而是在Clojure中,我们可以使用现有函数(并将它们组合成新的可重用函数)来完成这项工作,而在Java中,您必须编写(更多)自定义的一次性代码。(或者使用映射器库、注释和其他黑魔法:-))

    转换

    如上所述,在Clojure中,将头从一个请求复制到另一个请求是微不足道的。在典型的Java中,标头将由它们自己的类型(可能是标头)表示,因此,即使它们在两个库中具有相同的形状,它们仍然是不同的类型,我们需要从一种类型转换为另一种类型:

    // fake code <img src="https://file.lsjlt.com/upload/202306/28/f0by3zntb4l.gif" alt=":-)" />def toClientHdr(servlet.Header hdr) {  return new httpclient.Header(    name: hdr.name,    values: hdr.values)}clientRequest.headers =  servletRequest.headers    .map(toClientHdr)

    在Clojure中,toClientHdr是不必要的,因为我们只有映射,没有要从/映射到的类型。我们在这里的前提是,数据的“形状”在两端都是相同的,但即使不是,也更容易从一个转换到另一个,因为数据转换是FP的主要优势之一,尤其是Clojure。核心库中有许多有用的数据选择和转换功能,旨在以多种强大的方式进行组合。

    验证、封装?

    即使您同意使用一些具有强大功能的通用数据结构比将数据包装在类型中更有效,您也可能会担心类的其他好处,例如封装和数据验证。这超出了本文的范围,但请确保FP/Clojure具有满足这些需求的解决方案,尽管它们明显不同于OOP。

    到此,关于“Clojure与Java对比实例分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

    --结束END--

    本文标题: Clojure与Java对比实例分析

    本文链接: https://lsjlt.com/news/340596.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Clojure与Java对比实例分析
      这篇文章主要介绍“Clojure与Java对比实例分析”,在日常操作中,相信很多人在Clojure与Java对比实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Clojure与Java对比实例分析”的疑...
      99+
      2023-07-02
    • Kotlin与Java主客观对比的示例分析
      这篇文章将为大家详细讲解有关Kotlin与Java主客观对比的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。KotlinKotlin是一门相对比较新的JVM语言,JetBrains自2011年以来...
      99+
      2023-05-30
      kotlin java
    • Java中观察者模式与委托的实例对比分析
      这篇文章主要介绍“Java中观察者模式与委托的实例对比分析”,在日常操作中,相信很多人在Java中观察者模式与委托的实例对比分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中观察者模式与委托的实例对...
      99+
      2023-06-30
    • java中关于对象的实例比较分析
      本篇内容主要讲解“java中关于对象的实例比较分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java中关于对象的实例比较分析”吧!同类型对象的比较三个维度去比较同一性相等性相似性样例引入想象...
      99+
      2023-06-26
    • Java中对象比较的示例分析
      这篇文章主要介绍了Java中对象比较的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。元素比较基本类型的比较在Java中,基本类型的对象可以直接比较大小public&n...
      99+
      2023-06-29
    • Java对象实例分析
      这篇文章主要介绍“Java对象实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java对象实例分析”文章能帮助大家解决问题。1、寒冬的蛰伏这里的工作很繁忙,一年365天, 一天24小时几乎不停...
      99+
      2023-06-04
    • Android Coil和Glide实例对比分析
      这篇文章主要介绍“Android Coil和Glide实例对比分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android Coil和Glide实例对比分析”文章能帮助大家解...
      99+
      2023-07-05
    • nodejs中Express与Koa2对比的示例分析
      这篇文章给大家分享的是有关nodejs中Express与Koa2对比的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、先说结论目前没有看到Express会被koa2取代...
      99+
      2024-04-02
    • java静态和动态绑定的实例对比分析
      这篇文章主要介绍了java静态和动态绑定的实例对比分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java静态和动态绑定的实例对比分析文章都会有所收获,下面我们一起来看看吧。不同绑定的比较静态绑定发生在编译期...
      99+
      2023-06-30
    • Java Long类型对比分析
      Java Long类型对比 在开发的到一个很基础的问题 在代码中,两个Long类型数据比较用“==”,结果有时候true有时候false,原本以为Long会自动转long然后再比较,...
      99+
      2024-04-02
    • C++类与对象实例分析
      这篇“C++类与对象实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++类与对象实例分析”文章吧。运算符重载C++语...
      99+
      2023-06-30
    • Java中对HashMap的深度分析与比较(转)
      Java中对HashMap的深度分析与比较(转)[@more@]在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键。由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题。找遍了大大小小的...
      99+
      2023-06-03
    • MyISAM与InnoDB索引实现的对比分析
      小编给大家分享一下MyISAM与InnoDB索引实现的对比分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!MyISAM索引实现...
      99+
      2024-04-02
    • Python中Sync与Async执行速度快慢实例对比分析
      这篇文章主要讲解了“Python中Sync与Async执行速度快慢实例对比分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python中Sync与Async执行速度快慢实例对比分析”吧!1...
      99+
      2023-07-05
    • TypeScript与JavaScript对比及打包工具对比分析
      这篇文章主要介绍了TypeScript与JavaScript对比及打包工具对比分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇TypeScript与JavaScript对比及打包工具对比分析文章都会有所收获,...
      99+
      2023-07-05
    • VB.NET语言与VB语言对比的示例分析
      小编给大家分享一下VB.NET语言与VB语言对比的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!VB.NET语法对比旧语法 新语法 说明窗体装载事件,类初始化事件 Sub New procedure Sub New...
      99+
      2023-06-17
    • Aspectj与Spring AOP的对比分析
      1、简介 今天有多个可用的 AOP 库, 它们需要能够回答许多问题: 1、是否与用户现有的或新的应用程序兼容? 2、在哪里可以实现 AOP? 3、与自己的应用程序集成多快? 4、性能...
      99+
      2024-04-02
    • Component与PureComponent对比源码分析
      这篇文章主要介绍了Component与PureComponent对比源码分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Component与PureComponent对比源码分析文章都会有所收获,下面我们一起...
      99+
      2023-07-05
    • Java 输入输出 IO NIO AIO三兄弟对比分析对比分析
      目录1、Java I/O发展史    2、Java IO2.1 简介2.2 基础概念2.2.1 输入流和输出流2.2.2 字节流和字符流2.2.3 缓冲...
      99+
      2023-05-15
      Java 输入输出IO NIO AIO IO NIO AIO对比分析
    • Java中类与对象的示例分析
      这篇文章主要介绍Java中类与对象的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!类和对象在面向对象中,类和对象是最基本、最重要的组成单元。类实际上是表示一个客观世界某类群体的一些基本特征抽象。对象就是表示一...
      99+
      2023-06-20
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作