1

I have the following

class Person
  private String firstName;
  private String familyName;

  // Setters and Getters

And I have the following method

public String getFullName(Optional<Person> persons) {
  return persons
           .map(person -> (person.getFirstName() + " " + person.getFamilyName())).orElse("Invalid");
}

I just want to check if either first or last name is null, display "Invalid" for that person. I was thinking to add a method for validation but I am sure there is an easier way I cannot think about.

2
  • 1
    Passing Optional as a parameter is not a good idea. instead, having Optional<String> for the method would be better. something like this: Optional<String> getFullName(Person person) { if (person.getFamilyName() == null && person.getFirstName() == null) return Optional.empty(); return Optional.of(person.getFirstName() + " " + person.getFamilyName()); } Commented Apr 3, 2020 at 19:16
  • 2
    @HadiJ Good point. Also thought about that after answering the question. The developers cannot get used to the original purpose of Optional, being a safe way to return a nullable value. Having Optional as a method parameter is kinda violating this principle. Commented Apr 3, 2020 at 19:26

3 Answers 3

4

You are looking to Optional::filter, before the map:

return persons
        .filter(person -> person.getFamilyName() != null && person.getFirstName() != null)
        .map(person -> person.getFirstName() + " " + person.getFamilyName())
        .orElse("Invalid");

Which mean, if the family and first names are not null then create your concatination, otherwise return an Invalid message, or you can even throw an exception by using orElseThrow

Sign up to request clarification or add additional context in comments.

Comments

1

You can use filter for that:

public String getFullName(Optional<Person> persons) {
  return persons
           .filter(person -> Objects.nonNull(person.getFirstName()) && Objects.nonNull(person.getFamilyName()))
           .map(person -> (person.getFirstName() + " " + person.getFamilyName())).orElse("Invalid");
}

Comments

1

Another functional approach.

First create a predicate builder method for required field validation:

public static <T, F> Predicate<T> hasRequiredValue(Function<T, F> fieldGetter) {
    return fieldGetter.andThen(Objects::nonNull)::apply;
}

And modify the getFullName a little bit:

public Optional<String> getFullName(Person person) {
    return Optional.ofNullable(person)
                   .filter(hasRequiredValue(Person::getFamilyName))
                   .filter(hasRequiredValue(Person::getFirstName))
                   .map(p -> p.getFirstName() + " " + p.getFamilyName());
}

Then use it as follows:

Person person = ...
String fullName = getFullName(person).orElse("Invalid");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.