Best Java 8 Tips

1. Optional

   Optional is a seriously underrated feature that eliminates a lot of the NullPointerExceptions that plagued us. It is particularly useful at code boundaries (including the API you call and provide), because it allows you and the code you call to specify the expected results of the program running.

 However, without the necessary thought and design, it can lead to a small change that affects a large number of classes and also leads to poor readability. Here are some tips on how to use Optional efficiently.

   Optional should only be used for return types

 Cannot be parameters and properties. Fortunately, IntelliJ IDEA checks that you follow these recommendations with inspection turned on.

 

   Optional values ​​should be handled where they are used. IntelliJ IDEA's advice can prevent you from using Optional inappropriately, so you should immediately deal with any inappropriate use of Optional you find.

  You should not simply call get()

   The purpose of Optional is to indicate that the value may be empty, and to give you the ability to handle such situations. Therefore, it is very important to check before using the value. Simply calling get() without first checking with isPresent() can also lead to null pointer problems in some cases. Fortunately, IntelliJ IDEA will still check for this and warn you.

  But there are more elegant solutions. You can use the orElse method to give an alternative value when it is null. Or use the orElseGet method to handle the same situation as above. This example looks the same as the above, but this example is an implementation of the supplier interface that can be called, so if it's an expensive method, a lambda expression can be used for better performance.

 

2. Using Lambda Expressions

   Lambda expressions are one of the selling points of Java 8. Even if you haven't used Java 8 yet, you probably have some basic understanding by now. But it's still a new way of programming in Java, and it's not an obvious "best practice" either. Here are some guidelines that I follow.

   keep it short

   Functional programmers prefer to use longer lambda expressions, but it is easier for us programmers who have only used Java for many years to keep lambda expressions short. You even prefer to limit them to one line, making it easier to refactor longer expressions into a method.

 

 

  Turn them into a method reference. Method references may seem a little unfamiliar, but it's worth doing because in some cases it helps with readability, and I'll talk about readability later.

   

 

  Type information has been lost in lambda expressions, so you may find it more useful to have parameters that contain type information.

   As you can see, this is a little more cumbersome. Therefore I prefer to give the parameters a more meaningful name. Of course, IntelliJ IDEA will let you see the type information of the parameters, whether you do it or not.

   Even in a lambda expression of a functional interface:

  Designing for Lambda Expressions

   I think lambda expressions are a bit like generics - generics, we use them a lot (eg, to add type information to List<>), but less often we make a method or class generic (eg: Person<T> ). Again, it's like we use the Streams API wrapped by lambdas, but it's even rarer for us to create a method that takes a lambda expression parameter.

   If you find yourself in this situation, here are some great tips.

   IntelliJ IDEA can help you introduce a functional parameter

   This lets you use a lambda expression instead of an object to create a parameter. The benefit of this feature is that it recommends using an existing functional interface to match this specification.

   this will guide us

   Use an existing functional interface

   As developers become more familiar with Java 8 code, we'll know what to expect with interfaces like Supplier and Consumer, but creating an ErrorMessageCreator by itself would be surprising and time consuming. You can flip through the function package to see what the system itself has prepared for us.

   Add @FunctionalInterface annotation to functional interface

   If you really need to create your own functional interface, then you need to use this @FunctionalInterface annotation. This annotation does not seem to be of much use, but IntelliJ IDEA will prompt you if the interface does not meet the requirements of this annotation. For example you didn't specify the method to inherit:

   

   Too many methods specified:

 

   Use annotations in classes instead of interfaces:

 

   Lambda expressions can be used in any interface that contains only a single abstract method, but not in abstract classes that satisfy this requirement. Seems illogical, but the actual requirement must be.

 

3. Streams

 

  The Stream API is another big selling point of Java 8, and I think until now we still don't know how much this will change the way we code. But I found this to be a mixed feature.

   flow style

   Personally, I prefer to use the streaming style. Of course you don't have to do that too, but I found it helped me:

  •   At a glance, you can see what operations are there and in what order are they executed?

  • Easier to debug (although IntelliJ IDEA provides the ability to set a breakpoint on the line containing the lambda expression, split it on different lines for easier debugging)

  • Allows cancellation of an operation while testing

  • In debugging or testing, you can easily insert peek()

   

  In my opinion this is very concise. But using this approach doesn't save us many lines of code.

   You may need to adjust the code formatting settings to make the code look cleaner.

 

  

 

  Using method references

   Yes, you need a little time to get used to this weird syntax. But if used properly, it can really improve the readability of the code. Take a look at the following code:

 

  

 

  and a helper method using the Objects class:

 

 

  The following code is more clearly readable. IntelliJ IDEA usually knows how to fold a lambda expression.

 

 

  When iterating over the elements of a collection, use the Streams API whenever possible

   Or use new collection methods such as forEach. IntelliJ IDEA will suggest you to do this:

 

 

  It is generally more intuitive to use the Streams API than a combination of loops and if statements, for example:

   

 

  IntelliJ IDEA will suggest refactoring like this:

   

  The performance tests I've done have shown that this refactoring produces strange, unpredictable results, sometimes good, sometimes bad, and sometimes indistinguishable. As always, if your application is very concerned about performance, please measure it carefully.

   Use a for loop when iterating over an array

   Then again, using Java 8 doesn't mean you have to use the streaming API and the new methods of collections. IntelliJ IDEA will suggest some practices to refactor to stream, but you don't have to accept it (remember that inspections can be suppressed or turned off).

   Especially with a small array of primitive types, the performance of using a for loop is the best, and the code is more readable (at least for those new to the Streams API):

   

 No tips and tricks are set in stone, and you should decide for yourself where to use the Streams API and where to use loops.

  Reprinted: https://coyee.com/article/10666-java-8-top-tips

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324659801&siteId=291194637