【问题标题】:Mapping a list to Map Java 8 stream and groupingBy将列表映射到 Map Java 8 流和 groupingBy
【发布时间】:2015-09-01 20:08:58
【问题描述】:

我有这个简单的 Bean 类:

public class Book {     

public Book(Map<String, String> attribute) {
    super();
    this.attribute = attribute;
}
//key is isbn, val is author
private Map<String, String> attribute;

public Map<String, String> getAttribute() {
    return attribute;
}
public void setAttribute(Map<String, String> attribute) {
    this.attribute = attribute;
}

}

在我的主课中,我在列表中添加了一些信息:

    Map<String, String> book1Details = new HashMap<String, String>();
    book1Details.put("1234", "author1");
    book1Details.put("5678", "author2");
    Book book1 = new Book(book1Details);

    Map<String, String> book2Details = new HashMap<String, String>();
    book2Details.put("1234", "author2");
    Book book2 = new Book(book2Details);

    List<Book> books = new ArrayList<Book>();
    books.add(book1);
    books.add(book2);

现在我想将书籍列表转换为这种形式的地图:

Map<String, List<String>>

所以输出(上图)是这样的:

//isbn: value1, value2
1234: author1, author2
5678: author1

因此,我需要按 isbn 作为键和作者作为值对条目进行分组。一个 isbn 可以有多个作者。

我正在尝试如下:

Map<String, List<String>> library = books.stream().collect(Collectors.groupingBy(Book::getAttribute));

bean 的格式无法更改。如果 bean 有字符串值而不是 map,我可以做到,但坚持使用 map。

我已经编写了正确的传统 java 6/7 方式,但尝试通过 Java 8 的新功能来实现。感谢您的帮助。

【问题讨论】:

    标签: java collections lambda java-8


    【解决方案1】:

    你可以这样做:

    Map<String, List<String>> library = 
        books.stream()
             .flatMap(b -> b.getAttribute().entrySet().stream())
             .collect(groupingBy(Map.Entry::getKey, 
                                 mapping(Map.Entry::getValue, toList())));
    

    Stream&lt;Book&gt;,您将其与它包含的每个地图的流进行平面映射,以便您拥有Stream&lt;Entry&lt;String, String&gt;&gt;。从那里您可以按条目的键对元素进行分组,并将每个条目映射到您收集到值列表中的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      • 2015-02-11
      • 2015-12-27
      • 2017-12-24
      • 1970-01-01
      相关资源
      最近更新 更多