当前位置: 首页 > 知识库问答 >
问题:

列表映射的Java流映射

罗梓
2023-03-14

我有一个实体,看起来像这样:

public class Snippet {
    private Integer docId;
    private Integer page;
    private Payload payload;
}

输入数据是一个列表

我需要创建一个索引,允许我们迭代docid和页面,并获取相关的Snippet对象。

这样的数据结构:

地图

我可以使用Java流来获取地图

        List<Snippet> input = ....;
        input.stream()
        .collect(Collectors.groupingBy(
                    Snippet::getDocId, 
                    Collectors.toMap(Snippet::getPage, Function.identity())
                 )
        );

如何收集以获取列表作为最终地图值?


共有2个答案

章昱
2023-03-14

以下是另一个供您当前或未来考虑的备选方案。它使用地图界面的computeIfAbsent方法。

  • 创建最终的内容映射
  • 反复浏览代码段列表
  • 如果DocId不存在,则使用DocId键创建条目。然后尝试存储页面片段
  • 如果页面不存在,则使用页面作为键创建条目。然后将代码段存储在列表中

下面是一个使用记录代替类的示例。

record PayLoad(String getValue) {
    @Override
    public String toString() {
        return "[" + getValue() + "]";
    }
}

record Snippet(int getDocId, int getPage,
        PayLoad getPayLoad) {
    @Override
    public String toString() {
        return String.format("{%s, %s, %s}", getDocId,
                getPage, getPayLoad);
    }
}

创建一些数据

List<Snippet> input =
        List.of(new Snippet(1, 1, new PayLoad("A")),
                new Snippet(1, 2, new PayLoad("B")),
                new Snippet(1, 3, new PayLoad("C")),
                new Snippet(2, 1, new PayLoad("D")),
                new Snippet(2, 2, new PayLoad("E")),
                new Snippet(2, 3, new PayLoad("F")));

存储代码片段

Map<Integer, Map<Integer, List<Snippet>>> map =
        new HashMap<>();

for (Snippet s : input) {
    map.computeIfAbsent(s.getDocId(), v -> new HashMap<>())
            .computeIfAbsent(s.getPage(),
                    v -> new ArrayList<>())
            .add(s);
}

打印出来

map.forEach((k, v) -> {
    System.out.println(k);
    v.forEach((kk, vv) -> System.out
            .println("          " + kk + " -> " + vv));
});

印刷品

1
          1 -> [{1, 1, [A]}]
          2 -> [{1, 2, [B]}]
          3 -> [{1, 3, [C]}]
2
          1 -> [{2, 1, [D]}]
          2 -> [{2, 2, [E]}]
          3 -> [{2, 3, [F]}]
夏侯兴怀
2023-03-14

如您所见,收集器。分组依据(…) 获取收集器作为第二个参数。因此,只需使用收集器即可。分组依据(…)作为收集器的第二个参数。分组依据(…)

input.stream().collect(Collectors.groupingBy(
                        Snippet::getDocId,
                        Collectors.groupingBy(Snippet::getPage,
                                Collectors.toList())));

 类似资料:
  • 我有这个简单的Bean类: 在我的主类中,我在列表中添加了一些信息: 现在我想将图书列表转换为以下形式的地图: 因此,输出(上面的地图)如下所示: 因此,我需要按isbn作为关键字和作者作为值对条目进行分组。一个isbn可以有多个作者。 我尝试如下: 不能更改bean的格式。如果bean有字符串值而不是map,我可以这样做,但是要坚持使用map。 我已经写了传统的java 6/7方式来正确地做这件

  • 假设我有一个函数,它接受两个参数并返回一个值,那么可以将映射转换为流中的列表作为非终端操作吗?我能找到的最近的方法是使用地图上的forEach创建实例并将其添加到预定义列表中,然后从该列表中启动一个新流。还是我错过了什么? 经典的“在一长串单词中找出3个最常出现的单词” (现在我想流式处理该地图的入口集)

  • 如何从字符串列表中获取映射,其中索引是键,字符串是值? 如果我有这样的名单 我想要一张< code >地图 当我执行以下操作时,我得到一个错误 错误 所需类型:int提供:Object 当我将其转换为int或Integer时 我明白了 收集(java.util.function.Supplierjava.util.function.ObjIntConsumerjava.util.function.

  • 的默认行为 mapper() 在映射的 Table 到映射的对象属性中,每个属性都根据列本身的名称命名(特别是 key 属性 Column )这种行为可以通过几种方式进行修改。 从属性名称清楚地命名列 默认情况下,映射与 Column 与映射属性的相同-具体来说,它与 Column.key 属性对 Column ,默认与 Column.name . 指定给映射到的python属性的名称 Colum

  • 我得到的示例代码是 输入是一个啤酒对象列表,它返回一个包含所有啤酒的啤酒类型的地图。 现在我的问题。分组中的第二个和第三个论点是什么?我得到了第一个说明它是由什么分组的...但是第二个和第三个看起来有点随机。

  • 我在迭代一个对象内的列表时遇到了一个问题,该对象内嵌在另一个映射中。我的目标是迭代这个列表并生成一个映射 ,我希望使用streams和lamdas来实现这一点。 我在上面看到了,我需要通过迭代FolderBo中的elementList从elementBo创建一个带有map 的映射。folderBo本身就在Modelbo的地图内。