【问题标题】:Return Objects from Arraylist从 Arraylist 返回对象
【发布时间】:2014-04-03 14:18:57
【问题描述】:

我的问题是,我想从ArrayList“块”返回一个对象。 我的代码不起作用 - 错误提示 This method must return a result of type block

public block getBlockUnderneath (int x, int y){
    for(int i = 0; i<blocks.size(); i++){
         if (blocks.get(i).x == x) {
             return blocks.get(i);
         }
    }
}

【问题讨论】:

  • 什么是blocks?是List&lt;block&gt;吗?
  • 如果blocks.size() 返回 0 会怎样?
  • 如果列表中没有一个块与x 匹配,您期望会发生什么? (另外,我建议您了解增强的 for 循环...)
  • for(Block b : blocks) { if() return b; } ... 其中 List 块;

标签: java arraylist return


【解决方案1】:

你有两个问题:

  1. 如果 blocks.size()==0 您的方法没有返回任何内容
  2. 如果blocks 中的所有块都没有block.x==x,则您的方法不会返回任何内容。

在 Java 中,方法必须返回一个值,它被声明为这样做。

解决您的问题的最简单方法是在方法末尾return null

public block getBlockUnderneath (int x, int y){
    for(final block b : blocks){
         if (b.x == x) {
             return b;
         }
    }
    return null;
}

注意这使用了增强的for循环,这是在Java中循环Collections(或implements Iterable&lt;T&gt;)的推荐方式。

如果没有找到项目,更好的方法可能是抛出异常:

public block getBlockUnderneath (int x, int y){
    for(final block b : blocks){
         if (b.x == x) {
             return b;
         }
    }
    throw new NoSuchElementException();
}

在任何一种情况下,您都需要在调用此方法的代码中处理极端情况。

附:请坚持Java naming conventions。类应该在PascalCase - 所以你block 类应该被称为Block

只是为了好玩,在 Java 8 中:

public block getBlockUnderneath(int x, int y) {
    return blocks.stream().filter((b) -> b.x == x).findFirst().get();
}

【讨论】:

  • 因为时间限制,这是在当前版本中实现的方式
  • @Vash 我进行了一个快速实验(我确定你错了,但我想检查一下),你错了。 findFirst 只会遍历Stream,直到找到第一个匹配元素——filter 不会遍历整个Stream。正在运行(build 1.8.0-ea-b120
  • 你说得对。如果您使用 forEach 而不是 filter 和 findFirst(),我的意见将是有效的。
【解决方案2】:

您的方法的问题是存在未执行返回块的情况。在这种情况下,当方法未声明为 void 时,您必须为其声明退出点。

您可以使用 return 退出或抛出异常。选择取决于如果找不到请求的值,您的程序应该做什么。

public block getBlockUnderneath (int x, int y){
    for(int i = 0; i<blocks.size(); i++){
         if (blocks.get(i).x == x) {
             return blocks.get(i);
         }
    }
    return null; //or throw NoSuchElementException or IllegalStateException
}

此外,您还可以使用for-each loop 改进您的代码。此解决方案可能会为您提供更好的性能和代码安全性,因为它使用迭代器而不是按索引访问项目,这不一定有效。

在这种情况下,您访问同一个项目两次。

if (blocks.get(i).x == x) {
       return blocks.get(i);
}

完整示例

public Block findBlock(int x} { //The class name is Block

   for(Block block : blocks) {
      if(block.x == x {
         return block;  
      }
   }

    return null; 
}

还要注意返回 null 可能会导致问题,因此被认为是不好的做法。您可以避免 null,这要归功于检查的异常、默认值或使用 Null object

在 Java 8 中有这种通用编码模式的本地实现。使用 Guava library 中的 Optional&lt;T&gt; 类可以解决 Java

public Optional<Block> findBlock(int x} { //The class name is Block

   for(Block block : blocks) {
      if(block.x == x {
         return Optional.of(block);  
      }
   }

    return Optional.empty(); 
}

用法

  public void someActionWithBlocK() { 

      Optional<Block> block = findBlock(5);

      if(block.isPresent()) {
         //some action with block
      }
  }

【讨论】:

    【解决方案3】:

    你永远不能循环。

    如果循环中有return 语句,则编译器不会真正保证循环将执行并且您将返回。要解决这个问题,您还必须在循环之后 return

    或者,更好的是,为return 设置一个变量,如下所示:

    block ret = null;
    for(block b : blocks) {
        if(b.x == x) { // I'm going to go over this in a mo
            ret = b;
            break;
        }
    }
    return ret;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-15
      • 2018-08-04
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      • 2019-02-20
      • 2015-07-12
      • 1970-01-01
      相关资源
      最近更新 更多