我希望使用Java流来解决这类问题:
我有一个Library对象列表。
Library类包含一个Sections Map。 Sections包含BookShelf对象的List。 BookShelf包含Book对象的Map。
class Library {
Map<String, Section> sections = new HashMap<String, Section>();
String name;
public String toString() {
return name;
}
}
class Section {
List<BookShelf> bookShelves = new ArrayList<BookShelf>();
}
class BookShelf {
Map<String, Book> books = new HashMap<String, Book>();
}
class Book {
String name;
Book(String name) {
this.name = name;
}
}
我想知道的是所有拥有该书的图书馆对象叫做&#34; Java 8&#34;。我认为这是一个可以使用流来回答的查询,但是,编写各种流调用我得到了Book对象的集合,而不是根库对象。
流是否适合使用嵌入对象和集合?我怎么做到这一点?
下面是一个简单的代码,它使用传统的循环来找到答案:
List<Library> libraries = new ArrayList<Library>();
Library lib = new Library();
lib.name = "Houston Central";
libraries.add(lib);
Section section = new Section();
lib.sections.put("Reference", section);
BookShelf shelf = new BookShelf();
section.bookShelves.add(shelf);
Book book = new Book("Java 8");
shelf.books.put("Java 8", book);
book = new Book("Java 7");
shelf.books.put("Java 7", book);
/*
* Search for a Library containing a specific book
* using traditional loops.
*/
for(Library library : libraries) {
for (Section sec : library.sections.values()) {
for (BookShelf bookShelf : sec.bookShelves) {
for (Book b : bookShelf.books.values()) {
if (b.name.equals("Java 8")) {
System.out.println("Book is contained in Library " + library);
}
}
}
}
}
答案 0 :(得分:0)
流是否合适可能是品味和可读性偏好的问题。在我看来,流代码和lambdas不是最易读的代码,但也许是你学会做的事情。在任何情况下,基本方法是根据是否存在标题为“Java 8”的书来过滤库流,并将那些满足过滤谓词的库作为集合返回。过滤本身需要将每个库转换为书籍流,这需要两个平面图操作。然后我使用anyMatch匹配书名并终止给定库的流。您可以并行化我假设的过程,但我没有对并行流做很多事情。
下面提供的示例将搜索过程外部化。更合适的面向对象方法将包括Section和BookShelf类中的书籍搜索功能,这将大大提高可读性。
请记住,您要按顺序搜索图书,顺序搜索速度很慢。顺序搜索是O(n),而HashMap索引搜索是O(1)。我会在BookShelf类中包含一个索引。我在下面提供了一个顺序搜索算法的例子(未经测试)。
public Collection<Library> hasBook(Collection<Library> libraries, String title) {
return libraries.stream()
.filter(x->x.sections()
.stream()
.flatMap(y->y.bookShelves()
.stream()
.flatMap(z->z.books().stream()))
.anyMatch(b->b.title().equals(title)))
.collect(Collectors.toList());
}
答案 1 :(得分:0)
使用约翰莫里斯的解决方案进行调整以支持地图解决问题:
/*
* Using Streams
*/
public static Collection<Library> hasBook(Collection<Library> libraries, String title) {
return libraries.stream()
.filter(x->x.sections.values()
.stream()
.flatMap(y->y.bookShelves
.stream()
.flatMap(z->z.books.values().stream()))
.anyMatch(b->b.name.equals(title)))
.collect(Collectors.toList());
}
致电代码:
/*
* Search using streams
*/
Collection<Library> libs = hasBook(libraries, "Java 8");
for (Library l : libs) {
System.out.println("Book is contained in Library (via streams) " + l);
}