You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8中展开Map内列表并转为Map列表的最优方案

Java 8 实现Map列表展开为List<Map<String, String>>的最优方案

针对你提出的需求——把包含列表的Map<String, Object>展开成List<Map<String, String>>,我整理了两种场景的最优实现,用Java 8的Stream API来实现,代码简洁且覆盖边界情况。

场景1:仅存在一个列表类型的value

这是你例子中的情况,我们可以先定位到列表对应的键,提取其他键值对作为基础模板,再遍历列表元素生成新的Map:

import java.util.*;
import java.util.stream.Collectors;

public class MapFlattener {
    public static List<Map<String, String>> flattenSingleListMap(Map<String, Object> inputMap) {
        // 找到Map中唯一的列表类型键值对
        Optional<Map.Entry<String, Object>> listEntry = inputMap.entrySet()
                .stream()
                .filter(entry -> entry.getValue() instanceof List)
                .findFirst();

        // 边界处理:如果没有列表,直接返回转换后的单元素列表
        if (!listEntry.isPresent()) {
            return Collections.singletonList(convertAllValuesToString(inputMap));
        }

        String listKey = listEntry.get().getKey();
        List<?> listValues = (List<?>) listEntry.get().getValue();

        // 提取非列表的键值对,统一转换为String类型作为基础模板
        Map<String, String> baseTemplate = inputMap.entrySet()
                .stream()
                .filter(entry -> !entry.getKey().equals(listKey))
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> String.valueOf(entry.getValue())
                ));

        // 遍历列表元素,复制模板并替换列表键对应的value
        return listValues.stream()
                .map(item -> {
                    Map<String, String> newMap = new HashMap<>(baseTemplate);
                    newMap.put(listKey, String.valueOf(item));
                    return newMap;
                })
                .collect(Collectors.toList());
    }

    // 辅助方法:将Map中所有value转为String类型
    private static Map<String, String> convertAllValuesToString(Map<String, Object> map) {
        return map.entrySet()
                .stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> String.valueOf(entry.getValue())
                ));
    }

    // 测试示例
    public static void main(String[] args) {
        Map<String, Object> input = new HashMap<>();
        input.put("key1", "message1");
        input.put("key2", "message2");
        input.put("key3", Arrays.asList("abc", "xyz"));

        List<Map<String, String>> result = flattenSingleListMap(input);
        result.forEach(System.out::println);
        // 输出:
        // {key1=message1, key2=message2, key3=abc}
        // {key1=message1, key2=message2, key3=xyz}
    }
}

这个实现的优势:

  • 用Stream API替代传统循环,代码更简洁易读
  • 自动识别列表键,不需要硬编码指定
  • 完善的边界处理:没有列表时返回单元素列表
  • 所有value统一转为String,完全符合List<Map<String, String>>的输出要求

场景2:存在多个列表类型的value(笛卡尔积展开)

如果你的Map中可能存在多个列表,需要生成所有组合的Map(笛卡尔积),可以用flatMap来实现:

import java.util.*;
import java.util.stream.Collectors;

public class MultiMapFlattener {
    public static List<Map<String, String>> flattenMultiListMap(Map<String, Object> inputMap) {
        // 分离列表类型和非列表类型的键值对
        Map<String, List<?>> listEntries = inputMap.entrySet()
                .stream()
                .filter(entry -> entry.getValue() instanceof List)
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> (List<?>) entry.getValue()
                ));

        Map<String, String> baseTemplate = inputMap.entrySet()
                .stream()
                .filter(entry -> !(entry.getValue() instanceof List))
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> String.valueOf(entry.getValue())
                ));

        // 边界处理:无列表时返回单元素列表
        if (listEntries.isEmpty()) {
            return Collections.singletonList(baseTemplate);
        }

        // 初始化结果为基础模板,逐步遍历每个列表进行笛卡尔积展开
        List<Map<String, String>> result = Collections.singletonList(baseTemplate);
        for (Map.Entry<String, List<?>> entry : listEntries.entrySet()) {
            String currentKey = entry.getKey();
            List<?> currentValues = entry.getValue();
            result = result.stream()
                    .flatMap(existingMap -> currentValues.stream()
                            .map(value -> {
                                Map<String, String> newMap = new HashMap<>(existingMap);
                                newMap.put(currentKey, String.valueOf(value));
                                return newMap;
                            }))
                    .collect(Collectors.toList());
        }

        return result;
    }

    // 测试示例
    public static void main(String[] args) {
        Map<String, Object> input = new HashMap<>();
        input.put("key1", "message1");
        input.put("key3", Arrays.asList("abc", "xyz"));
        input.put("key4", Arrays.asList("123", "456"));

        List<Map<String, String>> result = flattenMultiListMap(input);
        result.forEach(System.out::println);
        // 输出:
        // {key1=message1, key3=abc, key4=123}
        // {key1=message1, key3=abc, key4=456}
        // {key1=message1, key3=xyz, key4=123}
        // {key1=message1, key3=xyz, key4=456}
    }
}

这个实现的优势:

  • 自动处理多个列表的笛卡尔积展开
  • 同样采用Stream的函数式风格,逻辑清晰
  • 保留了边界情况的处理

内容的提问来源于stack exchange,提问作者sparker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:53:48