【问题标题】:if-else inside for-each loopif-else 在 for-each 循环中
【发布时间】:2012-11-13 02:53:01
【问题描述】:

我是编程新手。我有这段代码:

public void findFilm ( String nameofFilm ) {  
   int index = -1;
   int i = 0;
   for( Film aFilm : list ) {  
      if( aFilm.gettitle().equals( nameofFilm )) {
         index = i;
         i++;
         break ;
      } 
   }
   if( index >= 0 ) {
      aFilm.print();
   }
   else {
      System.out.println(
         "The film " + nameofFilm + " does not belong to the collection" );
      } 
   }

更具体地说,我想搜索列表并查找它是否包含与我插入的名称相同的电影。有任何想法吗 ?非常感谢。

【问题讨论】:

  • 您的问题到底是什么?编译错误?运行时错误?
  • 我认为这是Code Review 的问题。但是我认为你的代码很好。
  • 到底是什么问题?

标签: java loops if-statement foreach


【解决方案1】:

aFilm 变量在 for 循环中定义。因此,它的范围仅限于循环,并且变量不能在循环之外使用。你可以这样重写循环:

Film foundFilm = null;
for (Film aFilm : films) {
    if (aFilm.getTitle().equals(nameOfFilm)) {
        foundFilm = aFilm;
        break;
    }
}
if (foundFilm == null) {
    ...
}
else {
    ...
}

不需要任何索引或递增计数器。

而且,为了使代码更简洁,您可以将第一部分提取到它自己的方法中,然后像这样重写它:

Film foundFilm = findFilmByTitle(films, filmTitle);
if (foundFilm == null) {
    ...
}
else {
    ...
}

【讨论】:

  • 大家都应该在回答之前寻找现有的答案。 @Garret Hall 已经用相同的解决方案回答了这个问题
  • @giorashc:了解并发系统中的竞争条件。此外,我认为我的回答带来了一些其他答案没有的观点。
  • 我还发现 Garret 的答案非常不同,而且不是最理想的。它混合了寻找胶片和打印它。我的回答清楚地将这两个部分分开。
  • 为什么要这么防御?我知道您可能在其他人发布时写了它,但我总是在写答案时收到答案通知,如果它们看起来相同,我会取消。
  • 我不想听起来有防御性。但正如我所说,我的答案与其他人不同。如果是这样,并且我的答案是在之前的答案之后写的,我会删除它。 119K声望,你不觉得我知道游戏规则吗?
【解决方案2】:

aFilm 仅在 for 循环中是本地的,您需要在 for 循环中打印它。

public void findFilm ( String nameofFilm ) {  
   for( Film aFilm : list ) {  
      if( aFilm.gettitle().equals(nameofFilm) ) {
         aFilm.print();
         return;
      } 
   }
   System.out.println(
      "The film " + nameofFilm + " does not belong to the collection");
}

【讨论】:

  • 我更喜欢在不打印任何内容的情况下返回 Film(最终为 null)。
  • 然后return aFilm 在循环内,return null 在循环外。
【解决方案3】:

使用像地图这样的数据索引:

SortedMap< String, Film > filmsByTitle = new TreeMap<>();
...
if( ! filmsByTitle.contains( newFilm.getTitle()) {
   filmsByTitle.put( newFilm.getTitle(), newFilm );
}

【讨论】:

    【解决方案4】:

    您可以选择功能性方法,例如通过Guava:

    public boolean containsFilm(List<Film> list, final String nameOfFilm) {
        Film film = Iterables.find(list, new Predicate<Film>() {
            @Override
            public boolean apply(Film film) {
                return film.getTitle().equals(nameOfFilm);
            }
        }, null);
        return film != null;
    }
    

    此外,我建议防御性地检查null(电影、标题等)。为了使示例简单,我已经离开了检查。

    【讨论】:

    • 如果电影不存在,上面会抛出 NoSuchElementException。您需要使用重载的 find() 方法,将默认值作为参数(在这种情况下为 null)。
    猜你喜欢
    • 2017-08-02
    • 2019-12-04
    • 1970-01-01
    • 2021-09-16
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多