当前位置: 首页 > 知识库问答 >
问题:

在For each中使用Lambda和Streams并返回结果

马魁
2023-03-14

我最近一直在学习lambda和streams,很早就被抛到了最深处。

我目前有一个书籍的数组列表,用户键入一个单词,如果这个单词等于书籍作者或标题,那么会调用并返回books toString(书籍的所有属性的格式都很好)。没有lambda很容易。但对于lambda,我似乎不知道如何才能把这一切都解决掉。

此外,使用lambda,我必须过滤掉数组中状态为“已损坏”或“已删除”的所有书籍。

问题是,我必须返回流的结果以最终显示在gui中,但似乎无法返回流的任何值。

我有一个谓词,它将尝试进行输入参数的匹配。我不知道这是否正确,我已经厌倦了尝试。

我只是想知道我需要做些什么必要的改变才能让它正常工作?

public String getBookByTitleOrAuthor(String titleOrAuthor) {
    books.stream()
         .filter(BookPredicate.matchTitleOrAuthor(titleOrAuthor))
         .filter(returnedBook -> returnedBook.getBookStatus() != 
            Book.bookStatus.Damaged && returnedBook.getBookStatus() != 
            Book.bookStatus.Deleted)
         .forEach(returnedBook -> returnedBook.toString());

}


// My predicate
public static Predicate<Book> matchTitleOrAuthor(String titleOrAuthor) {
    return b -> titleOrAuthor.equals(b.getTitle()) || 
    titleOrAuthor.equals(b.getAuthor());
}

提前谢谢你们!如果这是一个愚蠢的问题,对不起。

我的图书状态枚举和getBookstatus:

 public bookStatus getBookStatus() {
         return this.bookStatus;
    }

      public enum bookStatus {
       Available,
       Reserved,
       Borrowed,
       Damaged,
       Deleted

     }

共有2个答案

罗凯
2023-03-14

我们可以用很多方法做到这一点。我们应该在这里编写干净的代码,尽量避免在单个过滤器中使用多个加法条件,并将计算量大的过滤器移到较低的阶。其次,您将在此处获得匹配书籍的列表,如:

public List<String> getBookByTitleOrAuthor(String titleOrAuthor) {
        return books
            .stream()
            .filter(returnedBook.getBookStatus() != Book.bookStatus.Damaged)
            .filter(returnedBook.getBookStatus() != Book.bookStatus.Deleted)
            .filter(matchTitleOrAuthor(titleOrAuthor))
            .map(Book::toString)
            .collect(Collectors.toList());

}

如果只需要第一个匹配项,请使用以下选项:

public String getBookByTitleOrAuthor(String titleOrAuthor) {
        return books
            .stream()
            .filter(returnedBook.getBookStatus() != Book.bookStatus.Damaged)
            .filter(returnedBook.getBookStatus() != Book.bookStatus.Deleted)
            .filter(matchTitleOrAuthor(titleOrAuthor))
            .map(Book::toString)
            .findFirst()
            .orElse(null);
}

如果您想要书籍列表,则无需地图:

public List<Book> getBookByTitleOrAuthor(String titleOrAuthor) {
        return books
            .stream()
            .filter(returnedBook.getBookStatus() != Book.bookStatus.Damaged)
            .filter(returnedBook.getBookStatus() != Book.bookStatus.Deleted)
            .filter(matchTitleOrAuthor(titleOrAuthor))
            .collect(Collectors.toList());

}

如果您在这里看到,代码更干净、易于阅读,并且匹配过滤器仅在前两个为真损坏和删除时应用。

冯枫涟
2023-03-14

forEach返回void,而您需要字符串。不过,我不会选择字符串。该方法表示“我按标题或作者返回一本书”,因此用户希望看到一个图书实例。

public Book getBookByTitleOrAuthor(String titleOrAuthor) {
    return books.stream()
                .filter(BookPredicate.matchTitleOrAuthor(titleOrAuthor))
                .filter(b -> {
                               final Book.bookStatus status = b.getBookStatus();
                               return status != null && 
                                      status != Book.bookStatus.Damaged && 
                                      status != Book.bookStatus.Deleted; 
                })  // can be moved into a BookPredicate method as well
                .findAny()
                .orElseThrow(() -> new IllegalArgumentException("There is no book for the given author or title."));
}
 类似资料:
  • 问题内容: 我试图将一些for-each循环更改为lambda- 方法,以发现lambda表达式的可能性。以下似乎是可能的: 带lambda 但是下一个无效: 带lambda 最后一行的语法是否有问题,或者不可能从方法中返回? 问题答案: 在那里,从λ表达式,而不是从包含方法返回。而不需要流: 这里将流限制为与谓词匹配的那些项,然后返回带有第一个匹配条目的。 这看起来不如for循环方法有效,但实际

  • 我试图将一些for-each循环更改为lambda-方法,以发现lambda表达式的可能性。以下似乎是可能的: 使用lambda 但下一个就不起作用了: 带lambda 是最后一行的语法有问题还是无法从方法返回?

  • 我正在使用Spring Webflux和Spring Boot2,我的场景如下: 在返回之前,我如何将来自流量和正常产品列表的结果连接起来?没有反应控制器是可能的吗? 附言。我不想对从调用1获得的结果调用。block()和CompleteableFuture

  • 我有一个单词列表(编程语言),我想找出字母表中的哪个字母出现在这些单词中,然后将这些单词的字符串总长度相加,最后返回一个字母,返回与这些单词匹配的最长字符串。这是我到目前为止所得到的,我几乎没有进一步的进展。 这是我试图更好地理解java流的一个练习。 我期望的最终输出(结果)类似于“p:17” 由于字符p出现在单词php、python、perl、lisp中,它对这些单词求和并返回字符串长度为17

  • 问题内容: 我正在尝试执行新的JDK 8函数式编程领域中似乎是相对基本的事情,但是我无法使其工作。我有这个工作代码: 它接受一个数字列表,并产生可以打印出来的功能列表。但是,显式强制转换为Callable似乎是多余的。在我和IntelliJ中看来。我们都同意这也应该起作用: 但是我得到一个错误: 问题答案: 您遇到了Java 8目标类型的限制,该限制适用于方法调用的 接收者 。尽管目标类型在大多数

  • 我正试图做一件在新JDK似乎是相对基本的事情 它获取一个数字列表并生成一个可以将它们打印出来的函数列表。然而,Callable的显式强制执行似乎是多余的。对我和IntelliJ来说似乎是这样。我们都同意这也应该有效: 但是,我收到一个错误: