【问题标题】:For each loop not returning values?对于每个循环不返回值?
【发布时间】:2015-04-19 11:45:50
【问题描述】:

我目前正在制作一个程序,要求我对照文本文件(字典)中的所有单词检查数组中的单词,如果是则返回值 true,否则返回 false。 这是我目前的代码

 public static boolean isEnglishWord(String[] arrayOfWords) throws IOException {
     for (String line : Files.readAllLines(Paths.get("words.txt"), StandardCharsets.UTF_8)) {
         if(arrayOfWords[0] == line)
         {
             return true;
         }
         else
         {
             return false;
         }
     }
     return false;
    }

我知道这只会检查“行”中的第一个单词,我想知道如何移动到下一个单词以将其与数组中的单词进行比较

【问题讨论】:

  • 1.不要在字符串上使用==。 2. if (x) return true; else return false; 是 return x 的一个非常冗长的同义词。 3.只有找到东西才返回true,所以删除else子句。
  • 移除 if 和 else 条件并简单地返回 -> return (arrayOfWords[0].equalsIgnoreCase(line))
  • 你的方法没有意义。 isEnglishWord 听起来像是一个检查一个单词是否是英文单词的函数,而不是检查整个字符串列表是否包含一个英文单词。要么更改方法名称,要么只接受单个字符串作为参数。
  • @barq 我只是在测试数组中的第一个单词,我现在正在检查整个单词数组,看看它们是否都是英文单词。
  • 那么你应该只将这个词传递给你的函数,而不是整个数组。

标签: java loops for-loop each


【解决方案1】:

除了以明显的方式修复代码之外,您还可以考虑升级到 Java 8 习语:

return Files.lines(Paths.get("words.txt"), UTF_8)
            .anyMatch(w1 -> Stream.of(arrayOfWords)
                                  .anyMatch(w2 -> w2.equals(w1)));

此外,将 O(n2) 算法转换为 O(n) 的典型优化是使用 Set<String> 而不是字符串数组:

final Set<String> setOfWords = new HashSet<>(Arrays.asList(arrayOfWords));

然后你会写

return Files.lines(Paths.get("words.txt"), UTF_8)
            .anyMatch(setOfWords::contains);

或者,如果空间是一个问题,你可以对数组进行排序并使用 JDK 提供的二进制搜索,导致 O(n log n) 复杂度:

Arrays.sort(arrayOfWords);

和

return Files.lines(Paths.get("words.txt"), UTF_8)
            .anyMatch(w -> Arrays.binarySearch(arrayOfWords, w) >= 0);

最后,看起来您真正想要检查的是文件中的所有单词都是英文单词,而不是文件至少包含一个这样的单词。经过上述重构后,逻辑非常清晰,现在只需替换​​两个字符即可轻松更改:

return Files.lines(Paths.get("words.txt"), UTF_8)
            .allMatch(setOfWords::contains);

...这很好地展示了 FP 习惯用法的简洁性如何使您的代码更明显且更易于调试。

【讨论】:

    【解决方案2】:

    您只检查 arrayOfWords 中的第一个单词。您需要两个循环来检查文件中的所有单词与 arrayOfWords 中的所有单词。

    public static boolean isEnglishWord(String[] arrayOfWords) throws IOException {
         for (String line : Files.readAllLines(Paths.get("words.txt"), StandardCharsets.UTF_8)) {
             for (String word: arrayOfWords)
                return word.equalsIgnoreCase(line);    
         }
         return false;
    }
    

    【讨论】:

      【解决方案3】:

      首先在比较字符串时使用equals。其次,使用嵌套循环:

      public static boolean isEnglishWord(String[] arrayOfWords) throws IOException {
          for (String line : Files.readAllLines(Paths.get("words.txt"), StandardCharsets.UTF_8)) {
              for (String word : arrayOfWords) {
                  if(word.equals(line))
                  {
                      return true;
                  }
              }
          }
          return false;
      }
      

      这是假设您的方法只需将整个文件中的单个单词与数组中的单个单词匹配即可返回 true。我不确定这种方法有多大用处。

      【讨论】:

        【解决方案4】:

        删除这部分:

        public static boolean isEnglishWord(String[] arrayOfWords) throws IOException {
             for (String line : Files.readAllLines(Paths.get("words.txt"), StandardCharsets.UTF_8)) {
                 if(arrayOfWords[0].equals(line)) // use `equals()` instead of `==`
                 {
                     return true;
                 }
              //   else    --> If word is not found, you will eventually return false
               //  {
               //      return false;
               //  }
             }
             return false;
            }
        

        【讨论】:

        • 用 arrayOfWords[0].equalsIgnoreCase(line) 更好地比较字符串
        • @exoddus - OP 没有指定 那个。 :)
        猜你喜欢
        • 2020-02-08
        • 1970-01-01
        • 2016-05-21
        • 2016-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-30
        • 2013-12-30
        相关资源
        最近更新 更多