【问题标题】:How to handle return value when no object found找不到对象时如何处理返回值
【发布时间】:2020-01-15 17:49:53
【问题描述】:

我这里有以下一段代码,它旨在查找并返回一个产品对象,使用字符串输入与所有产品的名称进行比较。

public Product find(String input){

    for(int i = 0; i <Products.size();i++)
    {
         if(input ==Products.get(i).getName()){

         return Products.get(i);
        }   
    }   
}

我有两个问题。

A) 返回值在 IF 语句内部,所以主方法 find() 没有返回值。因此我收到一条关于此的错误消息。

B) 如果用户输入一个不存在的产品名称,那么将找不到产品,在 它不应该返回任何东西,但我不知道该怎么做。结果目前正在 用于删除产品,因此如果它传递一个要删除的空产品对象,这可能会导致 remove 方法中的错误输出。

我是编程新手,所以如果这是一个新手问题,我深表歉意,非常感谢任何帮助。

【问题讨论】:

  • 你应该使用equals()方法来比较字符串值:if(input.equals(Products.get(i).getName()))

标签: java object methods find


【解决方案1】:

(A) 和 (B) 实际上是同一个问题。 :-)

当没有找到匹配项时,您需要在循环之后执行以下两种操作之一的代码:

  1. 抛出异常,或

  2. 返回null

...或将Optional 作为Andreas shows you in his answer 返回。

如果找不到匹配项是常见且正常的,则返回 null 是标准的。如果找不到匹配项是异常且意外的,则抛出异常是标准的。


关于该代码的其他几点说明:

  1. 不要使用==比较字符串,使用equalsdetails

  2. 我假设Products 是实例变量(字段)或静态变量。如果是这样,它最初不应该被封顶。标准 Java 命名约定的实例和静态变量都以小写字母开头。

  3. 如果Products 是一个实例变量,我强烈建议使用this. 来访问它(this.Products,而不仅仅是Products),尽管这是风格问题; Java 确实允许您将其关闭。

  4. 如果Products 是一个数组或List(给定size() 方法,它看起来像一个列表),您最好使用增强的for 循环。

  5. 不鼓励过度使用空行。同样,只是风格问题。 :-)

  6. 最好与花括号 ({}) 的位置保持一致(在行尾,或单独在下一行,但不能同时在同一代码中)。 :-)

考虑到以上所有因素,假设Products 是一个实例变量:

public Product find(String input) {
    for (Product product : this.products) {
        if (input.equals(product.getName())) {
            return product;
        }   
    }   
    return null;
}

【讨论】:

  • 非常可靠的答案! ?
  • 非常感谢您在这方面的帮助,感谢您在帮助改进整体代码方面付出的额外努力!认为一旦读取 return 语句 - 无论是否在 for 循环内 - 整个 find 方法结束,这是否正确?此外,我从未见过这段代码(产品产品:this.products),理解它循环遍历所有数组元素,但是可以将我指向一个解释代码的哪些部分做什么的来源?
  • @InitialisingAttributes 正确,当执行return 语句时,不会执行方法中的其他代码finally 块除外)。 --- for (Product product : this.products) 被称为 增强 for 循环。有关更多详细信息,请参阅for 循环上的任何 Java 指南,例如The Java™ TutorialsGeeksforGeeksw3schools 或 ...
【解决方案2】:

从 Java 8 开始,推荐的不返回任何内容的方法是返回 Optional

public Optional<Product> find(String input) {
    for (Product product : products) {
        if (product.getName().equals(input)) {
            return Optional.of(product);
        }
    }
    return Optional.empty();
}

这会强制调用者检查是否返回了某些内容。

有关详细信息,请参阅例如Guide To Java 8 Optional.


对于 Java 8 之前的版本,或者只是老式的,返回一个 null 值:

public Product find(String input) {
    for (Product product : products) {
        if (product.getName().equals(input)) {
            return product;
        }
    }
    return null;
}

仍然由调用者检查是否返回了某些内容,即检查是否返回了null。然而,调用者很容易忘记这样做,这就是为什么首选使用Optional

【讨论】:

    【解决方案3】:

    我建议使用 Optional 类来实现您的目标。您的代码可以很容易地被此代码替换。假设您有一个产品列表,可以使用以下代码:

    public Optional<Product> find(String name) {
        List<Product> products = productDao.fetchAll();
        return products.stream().filter(p -> StringUtils.equals(p.name, name)).findFirst().orElseThrow(<Insert some excpeption builder>);
    }
    

    【讨论】:

    • 为什么是StringUtils.equals(...)?那是从哪个图书馆来的?为什么不是内置的Objects.equals(...)
    • 如果您永远不会返回空的可选项,而是抛出异常,那么使用 Optional 有什么意义?
    猜你喜欢
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2017-01-26
    • 2010-12-13
    • 2018-09-29
    • 1970-01-01
    相关资源
    最近更新 更多