[JAVA] To you who were told "Don't use Stream API" in the field

The temperature difference is great. I only want to go to work on warm days, but I'm thinking of accepting the bad routine of going to work on time because people don't have to be lazy by being tamed by habits.

"Stream abuse makes programs difficult to understand and maintain."

Effective Java 3rd Edition "Stream abuse makes programs difficult to understand and maintain"

Suddenly, this is the conclusion. The short and easy-to-read code is great. However, the Stream API is also easy to generate short and esoteric code, long and esoteric code. When implemented by someone who doesn't fully understand the Stream API, including myself, I must always be aware of the risk of poor program readability. This is a problem for programmers in the field, and the Stream API is not bad. If you want to write the Stream API, change the location. Before the concise code from the Stream API you implemented spreads all over the place due to abuse by copy and paste and becomes a problem.

Short and easy-to-read Stream API implementation

However, if it ends as it is, I'm sorry for some people who are still motivated to study Stream API, so I will introduce the code that makes Stream API more readable.

Now let's say you want to know which deals your employees are in charge of. How can I extract this information using a specific case list? As an implementation policy, 1, Acquisition of Record 2, Acquisition of the value to be treated as a key from Record 3, Create a map corresponding to the key value and Record Will be. The implementation by Stream API is as follows


/** 
*Implementation by Stream API.
*It is just an explanation code and does not implement connection operation, exception handling, etc.
*  @param salescodeList A list that stores code information that identifies the matter.
*  @return <K, V> = {Employee code,List of projects in charge}
*/
public Map<Integer, List<Record>> getSalesListGroupingByEmployeeCode (List<Integer> salesCodeList) {
    List<Record> recordList = searchBySalesCodeList(salesCodeList);
    return recordList.stream().collect(
        Collectors.groupingBy(recordList::getEmployeeCode));
}

First, I got a list of records. Then, make the list of acquired records into a Stream object. You can now work with the stream pipeline. Now let's sort out what we want to do with the stream pipeline. 1, I want to collect streams in a list 2, I want to perform grouping (mapping) using the employee code as a key So the implementation will be:

//Extracted the part using Stream API
recordList.stream(). //Convert List object to Stream object
    collect( //Declare to collect stream objects as a list
    Collectors.groupingBy( //Perform grouping
    recordList::getEmployeeCode) //Pass the key value used for grouping as an argument
    );

The StreamAPI focuses on "what to do", so such grouping and splitting would be a good example.

Implementation without Stream API

It is a change of direction when implemented by Stream API. If you disable the StreamAPI and return the same value as before, you'll probably have an implementation like this:


/** 
*Implementation that does not use Stream API.
*It is just an explanation code and does not implement connection operation, exception handling, etc.
*  @param salescodeList A list that stores code information that identifies the matter.
*  @return <K, V> = {Employee code,List of projects in charge}
*/
public Map<Integer, List<SalesRecord>> getSalesListGroupingByEmployeeCode (List<Integer> salesCodeList) {
    //HashMap to use as the return value of this method
    Map<Integer, List<SalesRecord> result = new HashMap<>();

    List<SalesRecord> recordList = searchBySalesCodeList(salesCodeList);
    for (List<SalesRecord> record : recordList) {
        int employeeCode = record.getEmployeeCode();
        //Here, already Key-Determine if a Value pair has been generated
        //If a pair has been created, the salesList can be obtained because the pair already exists in the result.
        List<SalesRecord> salesList = result.get(employeeCode);
        
        //If the pair does not exist, the list that stores the matter in charge cannot be stored, so a List is generated.
        if (salesList == null) {
            salesList = new ArrayList<>();
        }
        salesList.add(record);
        result.put(employeeCode, salesList);     
    }
    return result;
}

The number of lines has increased, and it's not very clear what you want to do.

Whether to use Stream API

The implementation example shown here was a better example to implement with Stream. However, there are some that should be implemented with a for statement instead of a Stream. If there are too many intermediate operations in the stream pipeline, some splitting may be necessary. After all, it's "which programmer prefers". It's not as clear as information hiding. If you're an enthusiastic supporter of the Stream API and you get tantrums when you're reviewing code that contains the Stream API and you're told "Stop the Stream API," you may not be there. In that case, actively adopt the Stream API and move around the site until you find an environment where you can maintain high code quality.

Recommended Posts

To you who were told "Don't use Stream API" in the field
[java8] To understand the Stream API
Do you use Stream in Java?
Try using the Stream API in Java
I tried to summarize the Stream API
The guy who can't handle errors in the stream
You may not want to use the remove method in ArrayList very often
When you want to use the method outside
For those who want to use MySQL for the database in the environment construction of Rails6 ~.
Use Java lambda expressions outside of the Stream API
[Rails] I don't know how to use the model ...
[Swift] Use UserDefaults to save data in the app
If you want to recreate the instance in cloud9
Java: Use Stream to sort the contents of the collection
What to do if you don't see the test code error message in the terminal console
Use JLine when you want to handle keystrokes on the console character by character in Java
Use collection_select to pull down the data stored in Active_Hash
To you who suffer from unexpected decimal points in Java
[Must-see for apprentice java engineer] How to use Stream API
How to create a placeholder part to use in the IN clause
I want to use the Java 8 DateTime API slowly (now)
How to call and use API in Java (Spring Boot)
Now is the time to get started with the Stream API
I was addicted to using Java's Stream API in Scala
What to do if you can't use the rails command
If you want to mock a method in RSpec, you should use the allow method for mock and the singleton method.
How to use Chain API
Java Stream API in 5 minutes
[Java] Introduction to Stream API
Use Redis Stream in Java
[Rails / Routing] How to refer to the controller in the directory you created
Use Docker and Keycloak to specify the access token and execute the API
If you want to include the parent class in Lombok's @builder
Let's consider the meaning of "stream" and "collect" in Java's Stream API.
The first thing to do before you can use Rails6 Ajax
Sample code to call the Yahoo! Local Search API in Java
What to do if you forget the root password in CentOS7
Leverage Either for individual exception handling in the Java Stream API
[Rails + Webpacker] I want to use images of assets! Until you can view the image in Vue.js