【问题标题】:Stream filter is not working for some reason流过滤器由于某种原因无法正常工作
【发布时间】:2018-08-14 12:57:38
【问题描述】:

我在这里的第一篇文章,我对 java(以及任何编程)非常陌生,如下所示:)

我需要从列表中打印出一个单词,但是 由于某种原因,我的流命令在使用 filter() 后找不到参数(字符串字),即使该字存在于列表中。 (我尝试了没有过滤器的 sout() 整个列表,并在输入中找到了它)。

private List<String> lines;

public reviews(List<String> lines) { 
    this.lines = lines;
}

public void NumberOfWords(String theWord) {

    lines.stream()
            .map(lines -> lines.split(" "))
            .map(words -> Arrays.toString(words))
            .map(word -> word.trim().toLowerCase())
            .filter(word -> word.equals(theWord))   // Something wrong with this line?
            .forEach(word -> System.out.println(word));

}

如果没有流过滤器(),输出如下所示:

[1, a, series, of, escapades, proofing, the, adage, that, what, is, good, for, the, goose, is, also, good, for, the , gander, ,, some, of, which, 偶尔, 有趣, but, none, of, of, which, 相当于, much, of, a, story, . ] [4,这,安静,,,,内省,和,娱乐,独立,是,值得,寻求,。 ] [1, 甚至, 粉丝, of, ismail, 商人, 的, 工作, ,, 我, 怀疑, ,, will, have, a, hard, time, sitting, through, this, one, . ] [3、a、肯定//etc........

使用过滤器,假设我们将有参数词:“good”。它存在,但方法不打印它。

【问题讨论】:

  • 为什么不打印出 each 流操作的结果,因为这样做肯定会显示您的错误假设?您的问题表明,将来您会想要在来这里之前做更多的调试。
  • @dbl 感谢您的回答!解释得很好,它对我理解问题有很大帮助:) 现在一切都清楚了。

标签: java filter java-stream


【解决方案1】:

你这里有一个逻辑错误:

.map(words -> Arrays.toString(words))
.map(word -> word.trim().toLowerCase())

这里的第一行将返回一个数组的字符串表示形式,因此结果将类似于: 从 “我是新手!”“我,是,一个,新手,!” 然后修剪这个字符串将得到完全相同的字符串 -> "I, am, a, newbie, !" 之后您将过滤这个完全相同的字符串(复合字符串,而不是简单的单词)到关键词。这最终会导致一个空列表。

如果您想在每次点击时打印匹配的单词,那么您可以使用 flatMap 通过以下方式执行此操作:

lines.stream()
    .map(line -> line.split(" "))
    .flatMap(Arrays::stream)
    .map(word -> word.trim().toLowerCase())
    .filter(word -> word.equals(theWord))
    .forEach(System.out::println);

如果您想打印出所需单词的总出现次数,只需使用这个:

System.out.println(lines.stream()
    .map(line -> line.split(" "))
    .flatMap(Arrays::stream)
    .map(word -> word.trim().toLowerCase())
    .filter(word -> word.equals(theWord))
    .count());

【讨论】:

    【解决方案2】:

    您的未过滤输出说明了一切。您无意中比较了整个单词数组而不是一个单词的字符串。

    问题在于Arrays.toString(words) 的映射。在这种情况下,您的流中的每个元素都会变成一个类似于以下内容的字符串: [1, a, series, of, escapades, demonstrating, the, adage, that, what, is, good, for, the, goose, is, also, good, for, the, gander, ,, some, of, which, occasionally, amuses, but, none, of, which, amounts, to, much, of, a, story, . ] (这是一个元素。)

    相反,您希望将 flatMap 您的单词行转换为单个单词,如下所示:

     lines.stream()                                     // Stream each line (each line is a string)
            .map(line -> line.split(" "))               // Map to an array of words per line
            .flatMap(lineArr -> Arrays.stream(lineArr)) // Map each word array into a stream of single words, and flatten each stream into a single one
            ...                                         // Now you can work with a stream of "single words"
    

    请注意,上面的“单个单词”是指两个空格之间的任何内容。正如您在上面的数组示例中看到的那样,您有一些空的或仅标点符号的条目,但这不应该影响您以后的equals 比较。

    【讨论】:

      猜你喜欢
      • 2013-12-28
      • 1970-01-01
      • 1970-01-01
      • 2016-12-06
      • 2012-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-07
      相关资源
      最近更新 更多