Home > OS >  How to correctly use the map operator in this Java 8 application in order to retrieve, modify and u
How to correctly use the map operator in this Java 8 application in order to retrieve, modify and u

Time:01-11

I am working on a Java 8 project based on Spring Boot and I am finding some difficulties trying to use a "functional" approach to my code. I admit that I remained at Java 7 approach and I am trying to improve my code with modern construct.

I have this service class method:

/`
 * Deactivate an user retrieved by its user ID
 * @throws NotFoundException 
 */
@Override
public Optional<User> deactivateUser(int userId) throws NotFoundException {
    
    Optional<User> retrievedUser = this.userRepository.findById(userId);
    
    return Optional.ofNullable(retrievedUser)      
            .map((user) -> retrievedUser.get())
            .orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));
}

As you can see it first retrieve an Optional<User> object using a Spring Data JPA repository.

Then I am trying to use functional approach (using map() operator) to implement the following behavior:

  1. Retrieve the User object contained into the Optional<User> object retrieved using the repository.

  2. If the retrieved Optional<User> object is not empty --> do some operation before return this object.

  3. If the retrieved Optional<User> object is empty --> throw the NotFoundException() exception.

I think that point 1 and 3 are ok. The problem is that I am not understanding how to correctly put some logic into the map() function, at the moment I have something like this:

.map((user) -> retrievedUser.get())

What exactly means it? I think that it put the User object retrieved by the retrievedUser.get() into an user variable that is returned. Is it my reasoning correct? (I am absolutely not sure).

My problem is that before to return this User object I need to perform some operation (basically update a field named isActive setting it to false and then update it using the Spring Data JPA save() method). How can I do it? Can you show me an example? I think that for me could be enough an example where I have a multi line function into the map() operator (also a function that first perform the retrievedUser.get() operation and that print it into another line, then I should be able to perform the needed logic by myself).

CodePudding user response:

The map method takes a Function object as a parameter. The Function is a generic interface that only has one method that acts like a callback, so in order to achieve your desired result, you have to implement this interface and pass it to the method. To do so, you can implement it by using a lambda expression (which is the way you're trying to do). In this case, the function will be called passing the object found by your repository.

You probably want something like this:

    return Optional.ofNullable(retrievedUser)
        .map((user) -> {
            // do your operation with the object
            return user;
        })
        .map(updatedUser -> userRepository.save(updatedUser))
        .orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));

Note that inside the lambda expression, you're dealing with the User and not with the Optional<User>, so there's no need to use .get() there. You should also note that the orElse/orElseThrow kind of functions return an instance of the object and not the Optional, so you'll have to change the return type of your method.

This article is a pretty good read if want to understand what each operation does and how to use them.

CodePudding user response:

You can write a function which accept an user and return an user for doing the logic of (2) . For example :

public User processUser(User user) {
    user.setActive(false);
    return user;
}

and then refer to this function in the map operator :

return Optional.ofNullable(retrievedUser
            .map((user) -> processUser(user))
            .orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));

You can further use method reference to simplify it to:

return Optional.ofNullable(retrievedUser
            .map(this::processUser)
            .orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));
  •  Tags:  
  • Related