[英]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 年的书籍的作者姓名。这需要一些示例数据 - 混合年份的书籍(目的是根据年份过滤一些数据)和带有姓名的作者。
有两个类: Author
和Book
。 让我们为这些创建一些示例数据:
作者:
作者有两个属性——姓名、书数。 让我们创建两个作者对象。 请注意作者的名字:
图书:
Book 具有三个属性 - 名称、年份和作者。 让我们创建三个书对象:
现在,构建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
。 这些null
和zero
是Author
类中定义的实例变量的默认值。 因此,对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)]
注意被覆盖的Object
的toString()
方法显示了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.