Java: 如何将 List<T> 转换为 Map<String,Object>

Java: how to convert a List<T> to a Map<String,Object>

我想建一个章节目录。我的数据结构如下。

private Map<String, ChapterPage> chapterPageRel;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class ChapterPage {
    @ApiModelProperty(value = "page list")
    private List<Integer> page;
    @ApiModelProperty(value = "page image list")
    private List<String> chapterImageId;
}

我的数据库数据如下

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "tb_electronic_material_resource_rel")
public class ElectronicMaterialResourceRelEntity {

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @TableField(value = "material_id")
    private Long materialId;

    @TableField(value = "chapter_image_id")
    private String chapterImageId;

    @TableField(value = "chapter_name")
    private String chapterName;

    @TableField(value = "page")
    private Integer page;
}

我想得到每个chapterName对应的页码和图片,其实我得到的是一张奇怪的图,如下图

List<ElectronicMaterialResourceRelEntity> materialResourceRelEntities = xxxx;
Map<String, Map<Integer, String>> collect =
    materialResourceRelEntities
    .stream()
    .collect(Collectors.groupingBy(ElectronicMaterialResourceRelEntity::getChapterName, Collectors.toMap(ElectronicMaterialResourceRelEntity::getSort, ElectronicMaterialResourceRelEntity::chapterImageId)));

但是我想问一下,如何收集class像Map<String,ChapterPage>

您可以将List转换为Json,然后将Json转换为Map

循环可能在这里更好,除非您需要在代码中的多个位置收集到这样的 ChapterPage 对象,或者您的输入已经是一个流并且您希望避免先将其具体化到列表中。只是为了演示如何仍然可以做到这一点,这是一个使用自定义下游 Collector:

的示例
Map<String, ChapterPage> res = input.stream()
        .collect(Collectors.groupingBy(ElectronicMaterialResourceRelEntity::chapterName, 
                Collector.of(
                        ChapterPage::new,
                        (c, e) -> {
                            c.getPage().add(e.page());
                            c.getChapterImage().add(e.chapterImageId());
                        },
                        (c1, c2) -> {
                            c1.getPage().addAll(c2.getPage());
                            c2.getChapterImage().addAll(c2.getChapterImage());
                            return c1;
                        }
                        )));

getter 和构造函数与您的代码不同,我在测试中为 ElectronicMaterialResourceRelEntity 使用了记录,为 ChapterPage 使用了没有注释魔法的 POJO。


我所说的“循环”不一定是指传统的循环,而是一种功能稍差的直接使用可变 HashMap:

的方法
Map<String, ChapterPage> res = new HashMap<>();
input.forEach(e -> {
    ChapterPage c = res.computeIfAbsent(e.chapterName(), k -> new ChapterPage());
    c.getPage().add(e.page());
    c.getChapterImage().add(e.chapterImageId());
});

以更简洁的方式产生相同的结果。