【问题标题】:How to convert if-else to Java8 Optional如何将 if-else 转换为 Java8 可选
【发布时间】:2021-03-26 05:54:13
【问题描述】:

如何更改以下代码以删除 if-else 并改用 Java8 Optional

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";
        else 
            foodItem = "Food";
        
        System.out.println(foodItem);
    }
}

【问题讨论】:

  • 你为什么要这样做?可选在这里显然是一个坏主意。也许你想要一个 switch 表达式。
  • 我想知道是否有任何 Java8 功能可以取消 if-else 或 switch
  • @astar 您可以使用 Map,使用 Java 8 添加的 getOrDefault. 这只是不清楚为什么您会使用正确的工具来完成这项工作(if/else 或 switch)。
  • 看看这个baeldung.com/java-replace-if-statements,它可能对你有帮助

标签: java java-8 optional


【解决方案1】:

Optional 不是 if/else 的通用替代品。这里不是一个好的选择。

我认为你可以设法使用 Optional 类似的东西:

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");

这只是一个完全无法阅读的混乱。

另一种选择是switch:这更好,因为它不会线性搜索所有案例,而是跳转到匹配的案例:

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

或者一个 switch 表达式(在 Java 12+ 中):

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

如果你想使用 Java 8 中添加的功能,你可以创建一个 Map:

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

然后使用map.getOrDefault(foodItem, "Food")。这基本上只是一种动态形式的开关。

【讨论】:

    【解决方案2】:

    Optional 不是if-else if-else 语句链的良好替代品。您可能希望在给定食物组的类中查找基于散列的数据结构,例如 HashSet

    @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");
    

    对于这样一个简单的用例来说,这个解决方案可能有点过头了,但是,这个解决方案是可扩展的。

    【讨论】:

      猜你喜欢
      • 2021-08-30
      • 2019-04-09
      • 2014-04-13
      • 2021-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多