所以,我有一个如下所示的输入 JSON:
[{
"added": "2014-02-01T09:13:00Z",
"author": {
"id": "1",
"name": "George R R Martin",
"added_on": "2013-02-01T09:13:00Z"
},
"book": {
"id": "12",
"name": "Game of Thrones",
"genre": "Fantasy Fiction"
}
},
{
"added": "2015-02-01T09:13:00Z",
"author": {
"id": "2",
"name": "Patrick Rothfuss",
"added_on": "2012-09-13T011:40:00Z"
},
"book": {
"id": "15",
"name": "The Name of the Wind",
"genre": "Fantasy Fiction"
}
}, {
"added": "2016-02-01T09:13:00Z",
"author": {
"id": "2",
"name": "Patrick Rothfuss",
"added_on": "2012-09-13T011:40:00Z"
},
"book": {
"id": "17",
"name": "The Wise Man's Fear",
"genre": "Fantasy Fiction"
}
}]
我需要根据 author.id 对其进行分组。一位作者将拥有一个对象和他所创作的所有书籍的列表。 这是我期望的输出:
[
{
"author": "George R R Martin",
"added_on": "2013-02-01T09:13:00Z",
"books": [
{
"book_name": "Game of Thrones",
"added": "2014-02-01T09:13:00Z"
}
]
},
{
"author": "Patrick Rothfuss",
"added_on": "2012-09-13T011:40:00Z",
"books": [
{
"book_name": "The Name of the Wind",
"added": "2015-02-01T09:13:00Z"
}, {
"book_name": "The Wise Man's Fear",
"added": "2016-02-01T09:13:00Z"
}
]
}
]
我尝试通过一个普通的 for 循环来完成它——它有效。但是,只是为了更多地了解 Streams,我想尝试使用 Streams。
我试过这个:
Map<Author, List<Book>> collect = authorsList.stream()
.collect(Collectors.groupingBy(AuthorBookObj::getAuthor,
Collectors.mapping(AuthorBookObj::getBook, Collectors.toList())));
但是,没有得到我需要的东西。相反,它创建了三个 map 而不是两个。
也试过这个:
Map<AuthorTuple, List<Book>> collect = authorsList.stream()
.collect(Collectors.groupingBy(authors -> new AuthorTuple(authors.getAuthor().getId(),
authors.getAuthor().getName(), authors.getAuthor().getAddedOn()),
Collectors.mapping(AuthorBookObj::getBook, Collectors.toList())));
它还为我提供了列表中的三个对象。我希望有两位作者和每位作者对应的书籍。
AuthBookObj:
public class AuthorBookObj
{
private String id;
private Author author;
private Book book;
private String added;
//getter, setter
}
public class Article
{
private String name;
private String id;
private String genre;
}
public class Author
{
private String name;
private String added_on;
private String id;
}
最佳答案
问题不在于您处理流的方式,而在于对象的相等性。
正确的方法是使用这段代码:
Map<Author, List<Book>> collect = authorsList.stream()
.collect(Collectors.groupingBy(AuthorBookObj::getAuthor,
Collectors.mapping(AuthorBookObj::getBook, Collectors.toList())));
但现在您正在比较 Author 对象,因为对象不同,您会得到三个条目。您需要在 Author 对象中添加一个 hashcode 和 equals 来比较作者 ID 上的对象。
//code generated from intellij.
// Author.java
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Author author = (Author) o;
return getId() == author.getId();
}
@Override
public int hashCode() {
return Objects.hash(getId());
}
关于java - 按 Java Streams 中的字段分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54488138/