根据条件 Java 获取可选

Fetching Optional based on condition Java

我正在尝试根据优先级和条件从多个 Optional 中获取值 让我们说在以下两组可选的 activity 中可以是 return 是步行和游泳。如果任一选项中有任何 activity,并且如果有游泳,那么应该优先考虑游泳而不是步行。如果没有活动,那么这将 return 为空。我写出来了,但是条件太多了,想看看有没有什么聪明的方法可以避免这么多条件

public Optional<Activity> getActivity(){
    Optional<Activity> activityWhenSunShines= getActivityWhenSunShiningForUser(u);
    Optional<Activity> activityWhenDayIsGood= getActivityWhenDayIsGoodForUser(u);
    if(activityWhenSunShines.isPresent() && Activity.SWIMMING == activityWhenSunShines.get()){
      return activityWhenSunShines;
    }else if(activityWhenDayIsGood.isPresent() && Activity.SWIMMING == activityWhenDayIsGood.get()){
      return activityWhenDayIsGood;
    }else if(activityWhenSunShines.isPresent()){
      return activityWhenSunShines;
    }else if(activityWhenDayIsGood.isPresent()){
      return activityWhenSunShines;
    }else{
      return Optional.empty();
    }
  }

这个代码

activityWhenSunShines.isPresent() && Activity.SWIMMING == activityWhenSunShines.get()

可以转换为更实用的样式,不用isPresent后跟[=​​14=]

activityWhenSunShines.map(a -> a == Activity.SWIMMING).orElse(false)

后3种情况可以用Optional.or替换(在Java 9中添加)。

这给你:

Optional<Activity> activityWhenSunShines = getActivityWhenSunShiningForUser(u);
Optional<Activity> activityWhenDayIsGood = getActivityWhenDayIsGoodForUser(u);

if(activityWhenSunShines.map(a -> a == Activity.SWIMMING).orElse(false)){
  return activityWhenSunShines;
} else if(activityWhenDayIsGood.map(a -> a == Activity.SWIMMING).orElse(false)){
  return activityWhenDayIsGood;
}
return activityWhenSunShines.or(() -> activityWhenDayIsGood);

患者:医生,医生!这锤子砸在脸上好痛!

医生:好的。那就别这样了。

可选(至少在 java 生态系统中)主要是不好的。流终端 return 值很好,其他的就没有了。

更好的选择是只设置一个 nullOptional 都不相关的数据结构设置。下一个最佳选择是使用 null(如果您更喜欢编译时检查,还可以添加一些无效注释)。一个非常糟糕的第三个解决方案是可怕的 Optional。

例如,在这里,为什么不设置 Activity.NOTHING,并指定 gAWSSFU 永远不会 return 为空?

如果您这样做,您的代码将如下所示:

Activity activityWhenSunShines = getActivityWhenSunShiningForUser(u);
Activity activityWhenDayIsGood = getActivityWhenDayIsGoodForUser(u);

return
  (activityWhenSunShines == Activity.SWIMMING || activityWhenDayIsGood) ? Activity.SWIMMING :
  activityWhenSunShines != Activity.NOTHING ? activityWhenSunShines :
  activityWhenDayIsGood;

如果您不喜欢 null 这里的任何东西,它是完全相同的代码,只需将 Activity.NOTHING 替换为 null 就可以了。

Optional 不组合(泛型具有 co/contra/in/legacy-variance,以便可组合。Optional 引入的无效维度不玩那个游戏;例如,您可以编写一个方法,该方法接受一个列表数字或其某些子类。您不能编写一个(类型安全的)方法来获取 StringOptional<String> 的列表。可选的也完全向后不兼容(例如 map.get(x)不是 return Optional<V> 并且永远不会,因为 java 不会破坏向后兼容性,尤其是这种经常使用的方法。如果你想要编译时检查的空安全,看看空注释框架,比如你的 IDE 中的那个(Eclipse 和 IntelliJ 都有自己的系统,完全支持编译时检查),或者使用例如检查器框架,它比eclipse 和 intellij 提供什么。