Meena Chaudhary
Meena Chaudhary

Reputation: 10675

What should be the return value for empty `Optional` type?

I have a chain of methods with one method having Optional return type as below

public Optional<Employee> find(long id) {

   for (Employee employee : this.employees) {
      if (employee.getId() == id) {
         return Optional.of(employee);
      }
   }
   return Optional.empty();
}

public Employee findlById(long id) {

   return find(id);
} 

Here the second method findById will have a compilation error as its own return type and the return type from find method are different.

Now if I check for the value and find it, I can return that object. But what should I return if Optional object is empty?

public Employee findlById(long id) {

   Optional<Employee> employee = find(id);
   if (employee.isPresent()) {
      return employee.get();
   }
   return // what??;
}

From the resources on the internet that I have read, you should never return null for an Optional object. So I am confused if not null than what?

Upvotes: 1

Views: 4833

Answers (5)

Dakshinamurthy Karra
Dakshinamurthy Karra

Reputation: 5463

Depends on the contract of the method. Suppose if the id is coming from a user input - it is quite possible that you might not have an employee with that ID. It is expected that you handle the error within the program. Since using Exceptions for control flow is generally a bad practice - return either an Optional<Employee> or null.

If you expect an Employee to exist for that ID - may be the ID is passed from a list you received from another part of program - throwing an Exception is preferred. (In that case, I suggest a different name for the function - something like getEmployeeDetails.

In the end, how you handle is totally dependent on your requirement - I doubt whether there is a good and single solution.

Upvotes: 3

Smit Thakkar
Smit Thakkar

Reputation: 64

    public Employee findlById(long id) { 
       Employee finalEmployee;
       Optional<Employee> employee = find(id); 
       if (employee.isPresent()) { 
          finalEmployee=employee.get(); 
       } 
       return finalEmployee; 
   }

Upvotes: -1

Tomer Gal
Tomer Gal

Reputation: 66

I dont have the full information to suggest you the specific answer you require but i can suggest 4 solutions that might fit :

  1. The findById method should return an optional it self. this gives you the advantage to decide for each case what you should return if the value was not found. i would suggest to combine both of the methods to one, it should look something like this, note that this would work only if this.employees is of type Collection:

    public Optional<Employee> findById(long id) {
        return this.employees.stream()
            .filter(employee -> employee.getId() == id)
            .findAny();
    }
    
  2. The findById method should return a default value, for example an empty employee with no values in his fields i suggest doing it like this:

    public Employee findlById(long id) {
       return find(id).orElse(new Employee());
    } 
    
  3. The findById method should throw an exception if the searched employee is not found, this can be done with using optional also:

    public Employee findlById(long id) {
        return find(id).orElseThrow(new RuntimeException("Cannot find required employee"));//Maybe throw your own exception
    }
    
  4. The findById should return null if the searched employee is not found this can be done using orElse method also:

    public Employee findlById(long id) {
        return find(id).orElse(null);
    } 
    

Upvotes: 0

Rishikesh Dhokare
Rishikesh Dhokare

Reputation: 3589

Its specific to your use case. The question is what should you return if you don't find an employee of a given Id. There are following choices -

  1. If its okay for the caller of findById() to get empty in return, return empty
  2. Throw an exception with some message custom to your use case

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201447

If you were returning an Optional type, then you could use Optional.empty() like

return Optional<Employee>.empty();

But since your return type is Employee your choices are change the return type to Optional<Employee> and use the above, return null; or throw some kind of Exception.

Upvotes: 5

Related Questions