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

时间:2019-05-16 07:19:14

标签: java lambda foreach java-stream

最近我一直在学习lambda和流,并且真的很早就投入了深渊。

我目前有一个书的数组列表,用户键入一个词,如果该词等于书的作者或书名,则会调用并返回书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 个答案:

答案 0 :(得分:2)

forEach返回void,而您需要String。不过,我不会选择String。该方法说“我按书名或作者归还一本书”,因此用户会期望有一个Book实例。

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."));
}

答案 1 :(得分:1)

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

import java.awt.Color;
import java.awt.Font;
import java.awt.*;
import java.awt.font.*;
import java.io.*;
import javax.swing.*;

public class TextFieldExample{

  public static void main(String[] args) {

    JFrame frame = new JFrame();
    frame.setLayout(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Font font1 = new Font("SansSerif", Font.BOLD, 20);

    JTextField textfield = new JTextField();
    textfield.setLocation(5, 5);
    textfield.setSize(150,20);  
    textfield.setFont(font1);
    textfield.setHorizontalAlignment(JTextField.CENTER);

    frame.getContentPane().add(textfield);  
    frame.setSize(350, 60);
    frame.setVisible(true);
  }
}

如果您只想首个比赛,则使用此:

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);
}

如果您看到的话,代码更简洁,易于阅读,并且仅在前两个为true时才应用匹配过滤器。