1

I'm using an Optional.of chain in Java to get a value,

Integer yearOfBirth = Optional.ofNullable(employee)
                              .map(Employee::getDateOfBirth)
                              .map(LocalDateTime::getYear())
                              .orElseThrow(new EmployeeException("Date of birth not set for {}", employee));

Is it possible to insert a log statement in the chain so that the date of birth is logged, without being consumed by the chain itself?

6
  • 4
    Why are you using Optional at all? Commented Jan 21 at 16:13
  • Yeah, Optional is intended for method return types Commented Jan 21 at 16:30
  • 1
    If you want to convert to a Stream, you may use its peek method, but it’s probably not worth it. You would need to go .stream() .peek(...) ... .findAny() .orElseThrow(...). Commented Jan 21 at 16:42
  • What would be the point of logging from within the call chain in your example? Just do log.info("dob {}", employee.getDateOfBirth()); before creating the Optional? Also, if your chain throws, you know there isn’t a date of birth, and if it doesn’t, you know there is (only you only know the year). Commented Jan 21 at 16:45
  • the employee object can be null, I've updated the code snippet with ofNullable Commented Jan 21 at 17:08

2 Answers 2

4

You can replace the getDayOfBirth reference with a lambda that logs it and then returns it:

Integer yearOfBirth = 
    Optional.of(employee)
            .map(e -> {
                   LocalDateTime dob = e.getDateOfBirth();
                   logger.info("Date of Birth is " + dob);
                   return dob;
             })
            .map(LocalDateTime::getYear())
            .orElseThrow(new EmployeeException("Date of birth not set for {}", employee));
Sign up to request clarification or add additional context in comments.

3 Comments

thanks, I was hoping for a single line solution, something like .map(Employee::getDateOfBirth) .passThrough(dob -> log.info("Date of Birth: {}", dob)) .map(LocalDate::getYear)
@mccarthyj You can always turn this into a method, and then call it in a single line
that might be the simplest solution, thank you
0

If you want to do it at multiple places, with different logics (logs or just any similar side-effect), you might benefit by adding a peek function in a common utility, as described in the below answer

How to peek on an Optional?

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.