In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains the "java functional coding structure and advantages", the content of the article is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in depth, together to study and learn "java functional coding structure and advantages" bar!
Preface
When garbage collection becomes mainstream, it eliminates all categories of problems that are difficult to debug, enabling the runtime to manage complex, error-prone processes for developers. Functional programming is designed to achieve the same optimizations for the algorithms you write so that you can work at a higher level of abstraction while performing complex optimizations at runtime.
Java's next generation of languages do not all occupy the same position in the language spectrum from imperative to functional, but they all show functional functions and idioms. Functional programming techniques are clearly defined, but languages sometimes use different terms for the same functional concepts, making it difficult to see similarities. In this article, I compared the functional coding styles of Scala, Groovy, and Clojure and discussed their advantages.
Imperative processing
I'm going to start by exploring a common problem and its imperative solution. Given a list of names, some of them contain a character. You are asked to return the name in a comma-separated string that does not contain a single-letter name, and the first letter of each name is capitalized. The Java code that implements the algorithm is shown in listing 1.
Listing 1. Imperative processing
Public class TheCompanyProcess {public String cleanNames (List listOfNames) {StringBuilder result = new StringBuilder (); for (int I = 0; I
< listOfNames.size(); i++) {if (listOfNames.get(i).length() >1) {result.append (capitalizeString (listOfNames.get (I) .append (",");}} return result.substring (0, result.length ()-1) .toString ();} public String capitalizeString (String s) {return s.substring (0,1). ToUpperCase () + s.substring (1, s.length ());}}
Because you have to deal with the entire list, the easiest way to solve the problem in listing 1 is to use an imperative loop. For each name, you need to check to see if its length is greater than 1, and then (if the length is greater than 1) append the first uppercase name to the result string followed by a comma. The last name in the final string should not contain a comma, so I removed it from the last return value.
In imperative programming, it is recommended that you do not perform actions at a lower level. In the cleanNames () method in listing 1, I perform three tasks: I filter the list to eliminate single characters, convert the first letter of each name in the list to uppercase, and then convert the list to a string. In an imperative language, I had to use the same low-level mechanism (iterating over the list) for all three tasks. Functional languages treat filtering, transformation, and transformation as common operations, so they provide you with ways to solve problems from different perspectives.
Functional processing
Functional programming languages are different from imperative languages in problem classification. Filter, transform, and transform logical categories are represented as functions. Those functions implement low-level transformations and rely on developers to write functions that are passed as parameters, thereby customizing the behavior of the functions. I can use pseudo code to conceptualize the problem in listing 1 as:
ListOfEmps-> filter (x.length > 1)-> transform (x.capitalize)-> convert (x, y-> x + "," + y)
With functional languages, you can model this conceptual solution without worrying about the implementation details.
Scala implementation
Listing 2 uses Scala to implement the processing example in listing 1. It looks like the previous pseudo code, containing the necessary implementation details.
Listing 2. Scala processing
Val employees = List ("neal", "s", "stu", "j", "rich", "bob") val result = employees.filter (_ .length () > 1). Map (_ .capitalize). Reduce (_ + "," + _)
For a given list of names, I first filter it to remove all names whose length is not greater than 1. The output of this operation is then provided to the map () function, which executes the provided block of code for each element of the collection and returns the transformed collection. Finally, the set of output from map () flows to the reduce () function, which combines each element based on the rules provided in the code block.
In this case, I combine each pair of elements and concatenate them with an inserted comma. I don't have to worry about the names of the parameters in the three function calls, so I can use the convenient Scala shortcut, that is, use _ skip the name. The reduce () function starts with the first two elements, combines them into one element, and becomes the first element in the next concatenation. While "browsing" the list, reduce () builds the required comma-separated strings.
I first showed the Scala implementation because I am familiar with its syntax, and Scala uses the industry names filter, map, and reduce for filtering, transforming, and transforming concepts, respectively.
Groovy implementation
Groovy has the same functionality, but they are named in a more consistent way with scripting languages such as Ruby. The Groovy version of the example processed in listing 1 is shown in listing 3.
Listing 3. Groovy processing
Class TheCompanyProcess {public static String cleanUpNames (List listOfNames) {listOfNames.findAll {it.length () > 1} .join {it.capitalize ()} .join (',')}}
Although listing 3 is structurally similar to the Scala example in listing 2, the method name is different. The findAll collection method of Groovy applies the provided code block, leaving the code block as the element of true. Just as Scala,Groovy includes an implicit parameter mechanism, predefined it implicit parameters are used for single-parameter code blocks. The collect method (the map version of Groovy) executes the provided block of code for each element of the collection. Groovy provides a function (join ()) that concatenates a collection of strings into a single string using the delimiters provided, which is exactly what is needed in this example.
Clojure implementation
Clojure is a functional language that uses reduce, map, and filter function names, as shown in listing 4.
Listing 4. Example of Clojure processing
(defn process [list-of-emps] (reduce str (interpose "," (map clojure.string/capitalize (filter #)
< 1 (count %)) list-of-emps))))) Clojure 的 thread-first 宏 thread-last 宏 使集合的处理变得更加简单。类似的 Clojure 宏 thread-first 可简化与 Java API 的交互。例如普遍的 Java 代码语句 person.getInformation(). getAddress().getPostalCode(),这体现了 Java 违反 迪米特法则 的倾向。这种类型的语句给 Clojure 编程带来一些烦恼,迫使使用 Java API 的开发人员不得不构建由内而外的语句,比如 (getPostalCode (getAddress (getInformation person)))。thread-first 宏消除了这一语法困扰。您可以使用宏将嵌套调用编写为 (->Person getInformation getAddress getPostalCode), you can nest as many layers as you want.
If you are not used to viewing Clojure, you can use the code in listing 4, whose structure may not be clear enough. A Lisp like Clojure works from the inside out, so you must start with the final parameter value, list-of-emps. The (filter) function of Clojure takes two parameters: the function to filter (anonymous in this case) and the collection to filter.
You can write a formal function definition for the first parameter, such as (fn [x]
< 1 (count x))),但使用 Clojure 可以更简洁地编写匿名函数。与前面的示例一样,筛选操作的结果是一个较少的集合。(map ) 函数将变换函数接受为第一个参数,将集合(本例中是 (filter ) 操作的返回值)作为第二个参数。Clojure 的 (map ) 函数的第一个参数通常是开发人员提供的函数,但接受单一参数的任何函数都有效;内置 capitalize 函数也符合要求。 最后,(map ) 操作的结果成为了 (reduce ) 的集合参数。(reduce ) 的第一个参数是组合函数(应用于 (interpose ) 的返回的 (str ))。(interpose ) 在集合的每个元素之间(除了最后一个)插入其第一个参数。 当函数嵌套过多时,即使最有经验的开发人员也会倍感头疼,如 清单 4 中的 (process ) 函数所示。所幸的是,Clojure 包含的宏支持您将结构 "调整" 为更可读的顺序。清单 5 中的功能与 清单 4 中的功能一样。 清单 5. 使用 Clojure 的 thread-last 宏 (defn process2 [list-of-emps](->> list-of-emps (filter # (
< 1 (count %)))(map clojure.string/capitalize)(interpose ",")(reduce str))) Clojure thread-last 宏采取对集合应用各种变换的常见操作并颠倒典型的 Lisp 的顺序,恢复了从左到右的更自然的阅读方式。在 清单 5 中,首先是 (list-of-emps) 集合。代码块中每个随后的表单被应用于前一个表单。Lisp 的优势之一在于其语法灵活性:任何时候代码的可读性变得很差时,您都可以将代码调整回具有较高可读性。 函数式编程的优势 在一篇标题为 "Beating the Averages" 的著名文章中,Paul Graham 定义了 Blub Paradox:他 "编造" 了一种名为 Blub 的虚假语言,并且考虑在其他语言与 Blub 之间进行功能比较: 只要我们假想的 Blub 程序员往下看一连串功能,他就知道自己是在往下看。不如 Blub 功能强大的语言显然不怎么强大,因为它们缺少程序员习惯使用的一些功能。但当我们假想的 Blub 程序员从另一个方向,也就是说,往上看一连串功能时,他并没有意识到自己在往上看。他看到的只不过是怪异的语言。他可能认为它们在功能上与 Blub 几近相同,只是多了其他难以理解的东西。Blub 对他而言已经足够好,因为他是在 Blub 环境中可以思考问题。 对于很多 Java 开发人员而言,清单 2 中的代码看起来陌生而又奇怪,因此难以将它看作是有优势的代码。但当您停止过于细化任务执行细节时,就释放了越来越智能的语言和运行时的潜能,从而做出了强大的改进。例如,JVM 的到来(解除了开发人员的内存管理困扰)为先进垃圾回收的创建开辟了全新的研发领域。使用命令式编码时,您深陷于迭代循环的细节,难以进行并行性等优化。从更高的层面思考操作(比如 filter、map 和 reduce)可将概念与实现分离开来,将并行性等修改从一项复杂、详细的任务转变为一个简单的 API 更改。 想一想如何将 清单 1 中的代码变为多线程代码。由于您密切参与了 for 循环期间发生的细节,所以您还必须处理烦人的并发代码。然后思考一下清单 6 所示的 Scala 并行版本。 清单 6. 实现进程并行性 val parallelResult = employees.par.filter(f =>F.length () > 1) .map (f = > f.capitalize). Reduce (_ + "," + _)
The only difference between listing 2 and listing 6 is that the .par method is added to the command flow. The .par method returns the parallel version of the collection on which subsequent operations are based. Because I specify the operation on the collection as a high-level concept, the underlying runtime is free to do more work.
Imperative object-oriented developers tend to consider using reuse classes because their language encourages classes as building blocks. Functional programming languages tend to reuse functions. Functional languages build complex general functions such as filter (), map (), and reduce () and customize them through functions provided as parameters. In functional languages, it is common to transform data structures into standard sets such as lists and mappings, because they can then be manipulated by powerful built-in functions.
For example, there are many XML processing frameworks in the Java environment, each of which encapsulates its own private version of the XML structure and delivers it in its own way. In a language such as Clojure, XML is transformed into a mapping-based standard data structure that is open to powerful transformation, reduction, and filtering operations that already exist in the language.
Concluding remarks
All modern languages include or add functional programming structures, making functional programming an integral part of future development. The next generation of Java languages implement powerful functional functions, sometimes with different names and behaviors.
Thank you for your reading, the above is the content of "java functional coding structure and advantages". After the study of this article, I believe you have a deeper understanding of the java functional coding structure and advantages, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.