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

将多地图“转置”到地图列表

楚俊杰
2023-03-14

假设我有一个多映射,如下所示:

MiddleName -> null
EmailAddress -> Toni@mymail.com, Mary@hermail.com, Paul@hismail.com
FirstName -> Toni, Mary, Paul
LastName -> Barry, null ,White
Id -> null
MiddleName -> null
EmailAddress -> Toni@mymail.com
FirstName -> Toni
LastName -> Barry
Id -> null

MiddleName -> null
EmailAddress -> Mary@hermail
FirstName -> John
LastName -> null
Id -> null

MiddleName -> null
EmailAddress -> Paul@hismail.com
FirstName -> Paul
LastName -> White
Id -> null
List result = (...)
map.forEach(h -> {
    MultiValueMap<String, String> m = new LinkedMultiValueMap();
    h.entrySet().stream().forEach(e -> {
        String[] ss = e.getValue() == null ? null : e.getValue().toString().split(",");
        if (ss != null) {
            Arrays.asList(ss).stream().forEach(s -> m.add(e.getKey(), s));
        }
    });
    if (m.size() > 0) {
        int x = m.values().stream().max((o1, o2) -> o1.size() - o2.size()).get().size();
        for (int i = 0; i < x; i++) {
            Map<String, String> n = (Map) h.clone();
            Iterator<Map.Entry<String, String>> it = n.entrySet().iterator();
            while( it.hasNext()){
                Map.Entry<String, String> e = it.next();
                List<String> ss = m.get(e.getKey());
                if(ss!=null) {
                    e.setValue(ss.get(i));
                }
            }
            result.add(n);
        }
    }
});

第一个步骤是将字符串拆分为一个数组,因为最初它是一个逗号分隔的字符串。然后,我找到任何值中的最大元素数,循环该次数的条目中的所有值,并用结果为每个值创建一个映射。坦率地说,我上周五写了这段代码,但我已经不能正确地阅读它...

所以,一开始这是一件简单的事情,但我最终陷入了混乱,有没有更好的方法来做这件事?

提前谢了。

共有1个答案

龙昊焱
2023-03-14

这样怎么样(如果我理解正确的话):

    Multimap<String, String> map = ArrayListMultimap.create();
    map.put("MiddleName", null);
    map.putAll("EmailAddress", ImmutableList.of("toni@gmail.com", "mary@gmail.com", "paul@gmail.com"));

    // that's the key with the "biggest" collection within the map
    int biggest = map.asMap().entrySet().stream().collect(Collectors.reducing(0, entry -> entry.getValue().size(), Integer::max));

    Multimap<String, String> newMap = ArrayListMultimap.create();

    // "padding" the collection when required
    map.keySet().stream().forEach(key -> {
        int currentSize = map.get(key).size();
        newMap.putAll(key, map.get(key));
        if (currentSize < biggest) {
            newMap.putAll(key, Collections.nCopies(biggest - currentSize, (String) null));
        }
    });

    System.out.println(newMap); // {MiddleName=[null, null, null], EmailAddress=[toni@gmail.com, mary@gmail.com, paul@gmail.com]}
}

从这里映射到某个Person对象相当容易。

 类似资料:
  • 问题内容: 如何转换 为? 这不起作用: 问题答案: 如果您只包含,则可以这样操作: 如果不是,则可以替换 为。

  • 我有这样一个代码: 你能帮我完成代码库吗?

  • 我正在努力使用Vavr将的减少为一个 有人能提供如何使用/的示例吗?

  • 问题内容: 我想转换一个从Java中8是这样的: 因为我有一个字符串列表,所以我想创建一个Map,键是列表的字符串,值是Integer(零)。 我的目标是计算字符串列表的元素(在我的代码中稍后)。 我知道以“旧”方式进行转换很容易; 但我想知道是否还有Java 8解决方案。 问题答案: 如前所述,参数必须是函数,因此必须更改为(可以使用任何其他参数名称代替)。 但是请注意,如果中存在重复项,此操作

  • 问题内容: 我需要转换为。我已经为这个问题苦苦挣扎了一段时间。 很明显如何转换为: 但是我找不到解决最初的问题。有一些易于使用的Java-8方法吗? 问题答案: 我想您很亲密,您需要将这些条目添加到a 并从那里收集。我使用了已经存在的,但是您也可以使用某种。 好吧,如果您不想增加这些实例的额外开销,则可以做些不同:

  • 问题内容: 是否有更优雅/内置的方式来反转Hashmap的键和值? 我目前有以下。 问题答案: 您可能会考虑使用Guava的实现之一。例如: 或更笼统地说: