Make Optional Mandatory

The title here may be a bit of an over-statement - especially in performance-dependant applications. However, Optional provides a great tool to clarify intent to other developers/API users, and if you don't use it already, I would suggest reading further.
This post is not arguing for wildly throwing Optional's into all of the code that you write, especially given that Optional itself can still be null. Therefore I would advise against passing Optional as a parameter to functions. but it is especially useful when making database calls that pass parameters. In the below case, the account balance will only be returned if the category is valid for the database. This makes the optional return far clearer than returning null to the service calling the function.
public Optional<AccountBalanceRecord> getAccountBalanceForCategory(AccountUid accountUid, CategoryUid categoryUid) {
    return persistenceContext.inTransaction(() -> accountStatements.getAccountBalance(accountUid, categoryUid));
}
The code acting on this API can also now become less verbose, and in turn be far easier to read.
public void processAccountBalance(AccountUid accountUid, CategoryUid categoryUid) {
  accountPersistenceService.getAccountBalanceForCategory(accountUid, categoryUid)
    .map(this::processAccountBalance)
    .orElseThrow(() -> new IllegalStateException("Category not found for the given account"));        
}
However, making a parameter optional can lead to some ambiguous behaviour - as can be seen from the below declaration. If a null value is passed to the optional here, a NullPointerException will be thrown, but no compile time warning will be thrown.
public int processValues(List<DataToBeProcessed> data, Optional<DataHandlingType> dataHandling) {
    if (dataHandling.isPresent()) {
        ... additional handling for data type
    }
    processData(data);
}
In most cases it makes more sense to utilise method overloading, making each method contain as few responsibilities as possible. In the refactored example this is far easier to test, and removes the ambiguity when debugging.
public int processValues(List<DataToBeProcessed> data) {
    processData(data);
}

public int processValues(List<DataToBeProcessed> data, DataHandlingType dataHandling) {
    ... additional handling for data type
    processData(data);
}
A second alternative to this is utilising @Nonnull/@NotNull parameter annotations, ensuring that tedious not null checks do not have to be added into methods.
public int processValues(List<DataToBeProcessed> data, @Nonnull DataHandlingType dataHandling) {
    ... additional handling for data type
    processData(data);
}
optional
comparisons