Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

How to change the below code to remove if-else and use Java8 Optional instead

public class IfTest {
    public static void main(String[] args) {
        String foodItem = "Apple";
        if(foodItem.equals("Apple") || foodItem.equals("A"))
            foodItem = "Fruit";
        else if(foodItem.equals("Potato") || foodItem.equals("P"))
            foodItem = "Vegetable";
            foodItem = "Food";
        System.out.println(foodItem);
                Why do you want to do that? Optional is clearly a bad idea here. Maybe you want a switch expression.
– ernest_k
                Mar 26, 2021 at 5:55
                @astar you could use a Map, using Java 8-added getOrDefault. It's just not obvious why you would use the right tool for the job (if/else or switch).
– Andy Turner
                Mar 26, 2021 at 6:00

Optional isn't a general-purpose replacement for if/else. It is not a good choice here.

I think you could contrive to use Optional something like this:

Optional.of(foodItem)
    .map(f -> f.equals("Apple") || f.equals("A") ? "Fruit" : f)
    .map(f -> !f.equals("Fruit") && (f.equals("Potato") || f.equals("P")) ? "Vegetable" : f)
    .filter(f -> !f.equals("Fruit") && !f.equals("Vegetable"))
    .orElse("Food");

which is just a total unreadable mess.

An alternative would be switch: this is better because it doesn't search through all the cases linearly, but rather jumps to the matching one:

switch (foodItem) {
  case "Apple": case "A":
    foodItem = "Fruit"; break;
  case "Potato": case "P":
    foodItem = "Vegetable"; break;
  default:
    foodItem = "Food";

Or a switch expression (in Java 12+):

foodItem = switch (foodItem) {
  "Apple", "A" -> "Fruit";
  "Potato", "P" -> "Vegetable";
  default -> "Food";

If you want to use a feature added in Java 8, you can create a Map:

Map<String, String> map = new HashMap<>();
map.put("Apple", "Fruit");
map.put("A", "Fruit");
map.put("Potato", "Vegetable");
map.put("P", "Vegetable");

And then use map.getOrDefault(foodItem, "Food"). That's basically just a dynamic form of the switch.

Optional is not a good replacement for a chain of if-else if-else statements. You might want to perform a look-up in a hash-based data structure such as HashSet inside a class for the given food group:

@Getter
@AllArgsConstructor         // basically getters and all-args constructor
public class FoodGroup {
    String name;
    Set<String> items;
List<FoodGroup> list = List.of(                            // I use Java-9+ static method
    new FoodGroup("Fruit", Set.of("Apple", "A")),          // for Java 8, use Arrays.asList(..)
    new FoodGroup("Vegetable", Set.of("Potato", "P")));
String foodItem = "Apple";
String result = list.stream()
                    .filter(group -> group.getItems().contains(foodItem))
                    .map(FoodGroup::getName)
                    .findFirst()
                    .orElse("Food");

This solution might be an overkill for such a simple use-case, however, this solution is scalable.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.