Java Programming Skills: Summary of if else Optimization Practice

  • 2021-10-13 07:46:55
  • OfStack

Directory 1. Optimize if-else2 with policy enumeration. Optimize if-else1 with 3-entry operators. Judge assignments according to if-else conditions, such as: 2. Judge calling methods according to if-else conditions, such as: 3. Optimize if with Stream. Optimize if-else5 with Map. Optimize if-else6 with enumeration. Optimize if-else summary with Optional class

1. Optimize if-else using policy enumeration

Seeing that many people on the Internet recommend using strategy mode to optimize if-else, I always feel that it is too heavy to engage in a bunch of strategy classes to optimize a large number of if-else, although the idea is very good, but it is likely to create many class objects inadvertently. If you want to use strategy mode to optimize a large number of if-else, there is actually a better way, which is an improvement of strategy mode + enumeration mode. I have written such an optimization article before, and click on this article directly in detail to understand: "Strategy Enumeration: Eliminate the elegant posture of using if-else in a large number of projects."

2. Optimize if-else using the 3-item operator

1. Judge the assignment according to if-else conditions, such as:


String id="";
if(flag){
    id="a";
}else{
    id="b";
}

Using the 3-item operator, you can directly optimize into 1 line of code:


id=flag?"a":"b";

2. Use if-else conditions to judge the calling method, such as:


Set<String> set1=new HashSet<>();
Set<String> set2=new HashSet<>();
if(flag){
    set1.add(id);
}else{
    set2.add(id);
}  

Using the 3-mesh operator, it can be directly optimized to:


Set<String> set1=new HashSet<>();
Set<String> set2=new HashSet<>();
(flag?set1:set2).add(id);

3. Use Stream to optimize the situation of excessive judgment conditions in if

The new feature of Jdk 1.8 Stream stream has three such API, anyMatch, allMatch and noneMatch, each of which has the following functions:

anyMatch: If any one of the judging conditions meets the conditions, true is returned; allMatch: If all the conditions are satisfied, return true; noneMatch: If all the conditions are not satisfied, return true;

The way they are used is actually very simple:


List<String> list = Arrays.asList("a", "b", "c","d", "");
// Arbitrary 1 If the string is not empty, it is true
boolean anyMatch = list.stream().anyMatch( s->StringUtils.isEmpty(s));
// If all string judgments are not empty; Otherwise, true
boolean allMatch = list.stream().allMatch( s->StringUtils.isEmpty(s));
// No 1 If the number of characters is judged to be empty, it is true
boolean noneMatch = list.stream().noneMatch( s->StringUtils.isEmpty(s));

It can be seen that according to the above three implementations, the situation that there are too many judgment conditions in if can be optimized to some extent. So, in which scenario is it more appropriate to use its optimization?

In daily actual development, we may see such code with many judgment conditions:


if(StringUtils.isEmpty(str1) || StringUtils.isEmpty(str2) ||
    StringUtils.isEmpty(str3) || StringUtils.isEmpty(str4) ||
    StringUtils.isEmpty(str5) || StringUtils.isEmpty(str6)
   ){
 .....
}

At this point, it can be considered that the stream flow is used for optimization, and the optimized code is as follows:


 if(Stream.of(str1, str2, str3, str4,str5,str6).anyMatch(s->StringUtils.isEmpty(s))){
 .....
 }

After this optimization, is it more elegant than the condition of piling up to one block in the pile of if?

Of course, this is only for OR conditions. If OR conditions are encountered, Stream can also be used for optimization, such as:


if(StringUtils.isEmpty(str1) && StringUtils.isEmpty(str2) &&
   StringUtils.isEmpty(str3) && StringUtils.isEmpty(str4) &&
   StringUtils.isEmpty(str5) && StringUtils.isEmpty(str6)
){
   .....
}

After optimization with Stream:


if(Stream.of(str1, str2, str3, str4,str5,str6).allMatch(s->StringUtils.isEmpty(s))){
  .....
}

4. Optimize if-else with Map

For process-oriented if-else statements with a large amount of optimization, Map can also be considered for optimization. Although to a certain extent, creating an extra map will occupy memory, it can be said that a little bit of memory is not worth mentioning for computers at this stage. Let's use a case to introduce the following--

Among some ancestral old codes, you may have encountered such a smelly and redundant writing of if-else:


public String getDay(String day){
    if("Monday".equals(day)){
       return " English class today ";
    }else if("Tuesday".equals(day)){
       return " I have a Chinese class today ";
    }else if("Wednesday".equals(day)){
       return " Math class today ";
    }else if("Thursday".equals(day)){
       return " Music class today ";
    }else if("Sunday".equals(day)){
       return " Programming class today ";
    }else{
       ......
    }
}

At this time, we can consider whether we can use Map optimization according to the specific scenario. The way to use Map optimization is to define an map of static in this class first, similar to this:


id=flag?"a":"b";
0

Once defined, it is optimized directly in the previous method using if-else:


id=flag?"a":"b";
1

After this optimization, the processing of judging and obtaining values in business methods is much fresher. Of course, this is only for if-else with a large amount. If there are fewer judgment statements, an additional map is defined to do it, which is vaguely suspected of gilding the lily.

Careful readers may find that when I defined map, I used an ImmutableMap, which is a class in Google Guava, and can generate an immutable Map object, which means that after initializing the definition, put cannot be modified later, and this feature can ensure the safety of threads. map, which is used to replace if-else, is required to be modified after initialization. Therefore, map generated by ImmutableMap can help us achieve this point well. In addition, the most important point is that using this ImmutableMap, you can realize chain programming, just like the chain writing defined above. If you use the traditional map definition, you have to assign values to map. put () and map. put () every time.

On the principle of ImmutableMap, I wrote a special article to introduce: "Java source code analysis: ImmutableMap source code analysis of the immutable set of Guava"

5. Optimize if-else using enumerations

As mentioned earlier, policy enumeration can be used to optimize a large number of if-else. Of course, if you only judge the code with different conditions to take values, you can consider directly using enumeration to optimize, and its effect is similar to that of map.

Or use if-else of the previous judgment course as an example to optimize.

First, define an enumeration in the class:


id=flag?"a":"b";
2

After the definition, it can be similar to the previous map, directly get the judgment value in the enumeration, and then directly return the obtained value, which is more elegant.


public String getDay(String day){
    return dayEnum.valueOf(day).value;
}

6. Optimize if-else using the Optional class

In practice, I've come across code like this that doesn't seem to be a problem, but if one of the attributes is unfortunately null, then, congratulations, you'll be happy to mention an NullPointerException exception.


id=flag?"a":"b";
4

To handle this possible null pointer exception, traditionally, you can write a heap of if-else statements to handle it, just like this-


id=flag?"a":"b";
5

As a person who hates if-else extremely, how can you tolerate the existence of this pile of nested code layer by layer!

When encountering this nested if-else judgment, we can consider using jdk1.8 new feature Optional class to optimize it. The optimized effect is as follows, and it is much more elegant at once.


id=flag?"a":"b";
6

Summarize

This article is here, I hope to give you help, but also hope that you can pay more attention to this site more content!


Related articles: