【问题标题】:Java Optional as parameter and manipulating objects in ifPresentJava 可选作为参数并在 ifPresent 中操作对象
【发布时间】:2016-09-21 14:14:40
【问题描述】:

我有办法

public String getSomething(Optional<String> name) {
    StringBuilder something = new StringBuilder("Hello");
    name.ifPresent(n -> something.append(n));
    return something.toString();
}

我使用 IntelliJ,它抱怨您不应该将 Optionals 用作参数而只能用作返回类型。我还读到您希望避免函数式编程中的副作用,并且您不应该操纵对象。

所以我一直在想如果这样做不是更好

public String getSomething(String name) {
    StringBuilder something = new StringBuilder("Hello");
    if (name != null) {
        something.append(name);
    }
    return something.toString();
}

使用 Optional 有什么好处吗?我可以看到的一个好处是该方法告诉您参数是可选的。

【问题讨论】:

  • 为什么要传递可选字符串?难道你不知道你有一个字符串要传递吗?
  • @MuratK。有时人们会在没有参数值的情况下调用我的方法。 String 只是作为一个例子,在我的真实案例中它实际上是一个 DateRange。然后我仍然想返回一个值。
  • @Tunaki 它确实稍微回答了我的第一部分问题。但是通过使用 Optional,我也可以使用 ifPresent,而另一个线程没有回答。

标签: java optional optional-parameters


【解决方案1】:

在这种情况下传递Optional 是可以的,但你可以写一些类似

 String nullableName = null;
 Optional<String> name = Optional.ofNullable(nullableName);
 StringBuilder something = new StringBuilder("Hello");
 // getSomething equivalent
 name.map(something::append).orElse(something);

您映射的不是空值或只是返回构建器

【讨论】:

    【解决方案2】:

    传递Optional 比传递null 更好。 IntelliJ 试图过于规范。假设是,在呼叫站点您这样做:

    Optional<String> nameOpt = ...
    nameOpt.ifPresent(name -> getSomething(name));
    

    是的,理想。希望这里nameOpt 没有参数...

    这里你可以使用地图

    Optional<String> sOpt = nameOpt.map(this::getSomething);
    

    public String getSomething(String name) {
        StringBuilder something = new StringBuilder("Hello");
        something.append(name);
        return something.toString();
    }
    

    这是完美的功能,IntelliJ 也会喜欢它。

    在 java 9 中,Optional 的能力将会增强。


    看来实际的问题是:有一个可能为空的字符串参数, 我们应该处理:

    Optional.ofNullableparameter)
    

    进一步,或传递参数。

    他们的 Optional map 也可以安全地链接处理可能的 String 并返回一些其他 Optional:

    // Get the length of the uppercased parameter, when it exists:
    Optional<Integer> lengthOpt = Optional.ofNullable(parameter)
        .map(s -> s.toUpperCase(Locale.DE))
        .map(String::length);
    

    如果参数是“Goßlung” - “GOSSLUNG” - Optional.of(8)。

    (该示例应该使用 OptionalInt,但那将是相同的。)

    【讨论】:

    • 调用者不一定有 Optional。调用者更有可能只有 Optional 的值或根本没有值。这就是为什么我需要检查它的存在。
    【解决方案3】:

    处理这个问题的最好方法是告诉调用者首先不要传递 null。

    这实际上是大多数 Java SE 的工作方式。例如,如果您尝试执行new URL(null),您将得到一个异常。 new BigDecimal(null)System.getProperty(null)ImageIO.read(null) 和许多其他人也是如此。

    您的方法也应该这样做。事实上,there exists a method 就是为了这个目的:

    public String getSomething(String name) {
        Objects.requireNonNull(name,
            "This method may not be called with a null argument.");
    

    调用代码应该对 null 值的存在负责,并且应该避免使用 null 调用您的方法。理想情况下,调用代码应将 null 视为异常值,并应尽可能避免处理 null。

    【讨论】:

      猜你喜欢
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      • 2019-07-19
      • 2018-01-03
      • 2015-02-28
      • 1970-01-01
      • 2012-12-29
      • 2014-02-07
      相关资源
      最近更新 更多