In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article will explain in detail how to be a better programmer. The editor thinks it is very practical, so I share it with you as a reference. I hope you can get something after reading this article.
Read this article and learn how to use declarative code with functional combinations to become a better programmer.
In many cases, declarative solutions with functional combinations provide a better degree of code than traditional imperative code. Read this article and learn how to use declarative code with functional combinations to become a better programmer.
In this article, we will take a closer look at three problem examples and examine two different techniques (imperative and declarative) to solve these problems.
All the source code in this article is open source and is available from. Finally, we will see how the lessons of this article can be applied to the field of database applications. We will use Speedment Stream as the ORM tool because it provides standard Java Streams corresponding to tables, views, and joins in the database, and supports declarative constructs.
There are actually countless candidate examples that can be used to evaluate code metrics.
1. Problem exampl
In this article, I chose three common problems that developers may encounter in their daily work:
1.1.SumArray
Iterate over the array and perform the calculation
1.2.GroupingBy
Parallel aggregation value
1.3.Rest
Using paging to implement REST interface
two。 Solution technology
As described at the beginning of this article, we will use these two coding techniques to solve the problem:
2.1 imperative solution
As an imperative solution, we use traditional code samples with for loops and explicitly variable state.
2.2 declarative solution
A declarative solution in which we combine various functions to form high-order composite functions that solve the problem, usually using java.util.stream.Stream or its variants.
3. Code indicator
However, the idea is to use SonarQube (in this case SonarQube Community Edition,Version 7.7) to apply static code analysis to different solutions so that we can derive useful and standardized code metrics for problem / solution combinations. These indicators will then be compared.
In this article, we will use the following code metrics:
3.1. LOC
"LOC" stands for "line of code" and is the number of non-blank lines in the code.
3.2. Statements
Is the total number of statements in the code. There may be zero or more statements on each line of code.
3.3. Cycle complexity
Represents the complexity of the code and is a quantitative measure of the number of linear independent paths of the source code program. For example, a single "if" clause displays two separate paths in the code. Read more on Wikipedia.
3.4 . Cognitive complexity
> SonarCube claims:
"Cognitive complexity changes the practice of using mathematical models to evaluate software maintainability. It starts with the precedent set by Cyclomatic Complexity, but uses human judgment to evaluate how the structure should be calculated and decides what should be added to the model as a whole, which produces a method complexity score, which makes programmers evaluate maintainability models more fairly than before."
You can read more on SonarCube's own page.
Typically, you need to envision a solution in which these metrics are small rather than large.
For recording, it should be noted that any solution designed below is just one way to solve any given problem. If you know a better solution, please feel free to pass the
4. Iterative array
Let's start with simplicity. The object of this question example is to calculate the sum of the elements in the int array and return the result as long. The following interfaces define the problem:
Public interface SumArray {long sum (int [] arr);} 4.1. Imperative solution
The following solutions use imperative technology to implement SumArray problems:
Public class SumArrayImperative implements SumArray {@ Override public long sum (int [] arr) {long sum = 0; for (int I: arr) {sum + = I;} return sum;} 4.2 declarative solution
This is a solution that uses declarative technology to implement SumArray:
Public class SumArrayDeclarative implements SumArray {@ Override public long sum (int [] arr) {return IntStream.of (arr) .mapToLong (I-> I) .sum ();}}
Note that IntStream:: sum returns only one int, so we must add the intermediate operation mapToLong ().
4.3. Analysis.
SonarQube provides the following analysis:
SumArray's code metrics are shown in the following table (usually lower):
Technical LOCStatements cycle complexity cognitive complexity Imperative12521Functional11220
This is its value in the chart (usually lower):
5. Parallel aggregation value
The object of this problem example is to group Person objects into different buckets, where each bucket constitutes the only combination of a person's year of birth and the country in which he or she works. For each group, the average salary should be calculated. Aggregations should be calculated in parallel using a common ForkJoin pool.
This is the (immutable) Person class:
Public final class Person {private final String firstName; private final String lastName; private final int birthYear; private final String country; private final double salary; public Person (String firstName, String lastName, int birthYear, String country, double salary) {this.firstName = requireNonNull (firstName); this.lastName = requireNonNull (lastName) This.birthYear = birthYear; this.country = requireNonNull (country); this.salary = salary;} public String firstName () {return firstName;} public String lastName () {return lastName;} public int birthYear () {return birthYear;} public String country () {return country;} public double salary () {return salary;} / / equals, hashCode and toString not shown for brevity}
We also define another immutable class called YearCountry as the grouping key:
Public final class YearCountry {private final int birthYear; private final String country; public YearCountry (Person person) {this.birthYear = person.birthYear (); this.country = person.country ();} public int birthYear () {return birthYear;} public String country () {return country;} / / equals, hashCode and toString not shown for brevity}
With these two classes defined, we can now define an example of this problem through the interface:
Public interface GroupingBy {Map average (Collection persons);} 5.1. Imperative solution
Implementing an imperative solution to the GroupingBy sample problem is not easy. This is a solution to the problem:
Public class GroupingByImperative implements GroupingBy {@ Override public Map average (Collection persons) {final List personList = new ArrayList (persons); final int threads = ForkJoinPool.commonPool () .getParallelism (); final int step = personList.size () / threads; / / Divide the work into smaller work items final List subLists = new ArrayList (); for (int I = 0; I
< threads - 1; i++) { subLists.add(personList.subList(i * step, (i + 1) * step)); } subLists.add(personList.subList((threads - 1) * step, personList.size())); final ConcurrentMap accumulators = new ConcurrentHashMap(); // Submit the work items to the common ForkJoinPool final List futures = new ArrayList(); for (int i = 0; i < threads; i++) { final List subList = subLists.get(i); futures.add(CompletableFuture.runAsync(() ->Average (subList, accumulators));} / / Wait for completion for (int I = 0; I
< threads; i++) { futures.get(i).join(); } // Construct the result final Map result = new HashMap(); accumulators.forEach((k, v) ->Result.put (k, v.average ()); return result;} private void average (List subList, ConcurrentMap accumulators) {for (Person person: subList) {final YearCountry bc = new YearCountry (person); accumulators.computeIfAbsent (bc, unused-> new AverageAccumulator ()) .add (person.salary ());} private final class AverageAccumulator {int count Double sum; synchronized void add (double term) {count++; sum + = term;} double average () {return sum / count;} 5.2. Declarative solution
This is a solution that implements GroupingBy using declarative constructs:
Public class GroupingByDeclarative implements GroupingBy {@ Override public Map average (Collection persons) {return persons.parallelStream () .clients (groupingBy (YearCountry::new, averagingDouble (Person::salary);}}
In the above code, I used some static imports from the Collectors class (for example, Collectors:: groupingBy). This does not affect the code metrics.
5.3. Analysis.
SonarQube provides the following analysis:
GroupingBy's code metrics are shown in the following table (usually lower):
Technical LOCStatements cycle complexity cognitive complexity Imperative5227114Functional17110
This is its value in the chart (usually lower):
6. Implement the REST interface
In this example question, we will provide a paging service for the Person object. The Persons that appears on the page must meet certain (arbitrary) conditions and be sorted in a specific order. The page is returned as an immutable list of Person objects.
This is a problem-solving interface:
Public interface Rest {/ * * Returns an unmodifiable list from the given parameters. * * @ param persons as the raw input list * @ param predicate to select which elements to include * @ param order in which to present persons * @ param page to show. 0 is the first page * @ return an unmodifiable list from the given parameters * / List page (List persons, Predicate predicate, Comparator order, int page);}
The size of the page is in a separate utility class called RestUtil:
Public final class RestUtil {private RestUtil () {} public static final int PAGE_SIZE = 50;} 6.1. Imperative implementation method public final class RestImperative implements Rest {@ Override public List page (List persons, Predicate predicate, Comparator order, int page) {final List list = new ArrayList (); for (Person person:persons) {if (predicate.test (person)) {list.add (person) }} list.sort (order); final int from = RestUtil.PAGE_SIZE * page; if (list.size ()
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.