繁体   English   中英

为什么流过滤器在下面的代码片段中不起作用

[英]Why does stream filter not work in the below code snippet

考虑下面的代码片段,它给出了null 你能帮忙解决这个问题吗:

//model class
public class Author {
    private String name;
    private int countOfBooks;
    // setters and getters left for brevity
}

//model class
public class Book {
    private String name;
    private int year;
    private Author author;
    // setters and getters left for brevity
}

现在,假设我们要过滤掉 2005 年或之前出版的书籍。我们可能会过滤两次,如下所示:

// main class 
public static void main(String[] args) {
    List<Author> authors = Arrays.asList(new Author("Venkat", 10),new Author("Richord", 8));

    List<Book> books = Arrays.asList(new Book("Venkat", 2006, new Author()));

    books.stream()
         .filter(book -> book.getYear() > 2005)  // filter out books published in or before 2005
         .map(Book::getAuthor)                   // get the list of authors for the remaining books
         .filter(Objects::nonNull)               // remove null authors from the list
         .map(Author::getName)                   // get the list of names for the remaining authors
         .forEach(System.out::println);          // print the value of each remaining element
}

如果您查看books.stream()上的条件,您可以看到有一个特定条件,您可以获取书籍的所有作者:

.map(Book::getAuthor)              // get the list of authors for the remaining books

但是,在您的books声明中,您将书籍声明为:

List<Book> books = Arrays.asList(
            new Book("Venkat",2006,new Author())
    );

根据您的班级声明,这将创建一本书,标题为“Venkat”,年份为“2006”。 对于本书的作者,您调用了没有参数的new Author() 根据您对作者的类声明,这将创建一个具有空名称和空 countOfBooks 的作者。

相反,您的图书声明应该类似于:

List<Book> books = Arrays.asList(
            new Book("Venkat",2006,authors[0])
    );

或者

List<Book> books = Arrays.asList(
            new Book("Venkat",2006,new Author("Sekhar", 1))
    );

您正在尝试的示例打算打印年份大于 2005 年的书籍的作者姓名。这需要一些示例数据 - 混合年份的书籍(目的是根据年份过滤一些数据)和带有姓名的作者。

有两个类: AuthorBook 让我们为这些创建一些示例数据:


作者:

作者有两个属性——姓名、书数。 让我们创建两个作者对象。 请注意作者的名字:

  • name = "HG Wells",书数 = 2。
  • name = "Harper Lee",书数 = 1。


图书:

Book 具有三个属性 - 名称、年份和作者。 让我们创建三个书对象:

  • name = "War of the Worlds", year = 1898, author = "HG Wells"(作者在上面创建:1)。
  • name = "The Time Machine", year = 1895, author = "HG Wells"(作者在上面创建:1)。
  • name = "To Kill a Mockingbird", year = 1960, author = "Harper Lee"(作者在上面创建:2)。


现在,构建Author对象:

Author hgWells = new Author("H. G. Wells", 2);
Author hLee = new Author("Harper Lee", 1);

注意:也可以使用以下构造函数构建Author对象:

Author hgWells = new Author();

这将构建一个 author 对象,其 name 值为null , book count 值为zero 这些nullzeroAuthor类中定义的实例变量的默认值。 因此,对getName()方法的调用将返回null


并且,一些Book对象:

Book book1 = new Book("War of the Worlds", 1898, hgWells);
Book book2 = new Book("The Time Machine", 1895, hgWells);
Book book3 = new Book("To Kill a Mockingbird", 1960, hLee);


创建书籍列表:

List<Book> books = Arrays.asList(book1, book2, book3);
System.out.println(books);

这将打印:

[(War of the Worlds, 1898 - H. G. Wells), (The Time Machine, 1895 - H. G. Wells), (To Kill a Mockingbird, 1960 - Harper Lee)]

注意被覆盖的ObjecttoString()方法显示了Book对象的所有属性细节。


筛选书籍:

现在,我们有一些带有作者数据的书籍可供使用。 让我们过滤它们。 在这个例子中,我将打印 20 世纪的书籍(即过滤出版年份大于 1899 年、1900 至 1999 年的书籍;我们只有 19 世纪和 20 世纪的书籍)。

由于我们使用流; 过滤器是一个 lambda。 这里是:

Predicate<Book> yearFilter = book -> book.getYear() > 1899;

让我们将过滤器应用于书籍列表:

books.stream()
    .filter(yearFilter)
    .map(book -> book.getAuthor().getName())
    .forEach(authorName -> System.out.println(authorName));

这将打印: Harper Lee 只有一本书的出版年份是 20 世纪——年份是 1960 年,并印有作者姓名。

评论:

这是创建一些测试数据并使用它来处理流的过滤器功能的示例。


编码:

import java.util.*;
import java.util.stream.*;
import java.util.function.*;

class Author {

    private String name;
    private int bookCount;

    public Author() {
    }

    public Author(String name, int bookCount) {
        this.name = name;
        this.bookCount = bookCount;
    }

    public String getName() {
        return name;
    }

    public int getBookCount() {
        return bookCount;
    }
}

class Book {

    private String name;
    private int year;
    private Author author;

    public Book(String name, int year, Author author) {
        this.name = name;
        this.year = year;
        this.author = author;
    }

    public String getName() {
        return name;
    }

    public int getYear() {
        return year;
    }

    public Author getAuthor() {
        return author;
    }

    @Override
    public String toString() {
        return "(" + name + ", " + year + " - " + author.getName() + ")";
    }

}

public class TestingLambdas2 {

    public static void main(String [] args) {

        Author hgWells = new Author("H. G. Wells", 2);
        Author hLee = new Author("Harper Lee", 1);

        Book book1 = new Book("War of the Worlds", 1898, hgWells);
        Book book2 = new Book("The Time Machine", 1895, hgWells);
        Book book3 = new Book("To Kill a Mockingbird", 1960, hLee);

        List<Book> books = Arrays.asList(book1, book2, book3);
        System.out.println("> All books:" + books);

        Predicate<Book> yearFilter = book -> book.getYear() > 1899;
        System.out.println("> Filtered book author(s):");
        books.stream()
                .filter(yearFilter)
                .map(book -> book.getAuthor().getName())
                .forEach(authorName -> System.out.println(authorName));
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM