考虑下面的代码片段,它给出了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
}
答案 0 :(得分:0)
如果您查看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()
。根据您对author的类声明,这将创建一个名称为null且countOfBooks为null的作者。
相反,您的图书声明应该类似于:
List<Book> books = Arrays.asList(
new Book("Venkat",2006,authors[0])
);
OR
List<Book> books = Arrays.asList(
new Book("Venkat",2006,new Author("Sekhar", 1))
);
答案 1 :(得分:0)
您要尝试的示例打算打印年份大于2005年的书籍的作者姓名。这需要一些示例数据-混合年份的书籍(目的是根据年份过滤某些数据)和具有名称的作者
有两个类:Author
和Book
。让我们为它们创建一些示例数据:
作者:
作者具有两个属性-名称,书数。让我们创建两个作者对象。请注意作者的名字:
图书:
书具有三个属性-名称,年份和作者。让我们创建三个书本对象:
现在,构建Author
对象:
Author hgWells = new Author("H. G. Wells", 2);
Author hLee = new Author("Harper Lee", 1);
注意:也可以使用以下构造函数来构建Author
对象:
Author hgWells = new Author();
这将构建一个作者对象,其名称值为null
,帐簿数量值为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
的{{1}}方法显示了toString()
对象的所有属性详细信息。
过滤书籍:
现在,我们有一些带有作者数据的书可供使用。让我们过滤它们。在此示例中,我将印刷20世纪的书籍(即,在1900年至1999年之间出版的过滤器书籍出版年份大于1899年;我们只有19世纪和20世纪的书籍)。
由于我们正在使用流;过滤器将成为lambda。在这里:
Book
让过滤器应用于书籍列表:
Predicate<Book> yearFilter = book -> book.getYear() > 1899;
这将打印: Harper Lee 。在20世纪只有一本书出版年份-1960年,并印有作者的名字。
评论:
这是一个示例,用于创建一些测试数据并将其用于流的过滤器功能。
代码:
books.stream()
.filter(yearFilter)
.map(book -> book.getAuthor().getName())
.forEach(authorName -> System.out.println(authorName));