集合 -Java- 笛卡尔积、平铺
作者:alexgaoyh
- 2024-01-19 河南
本文字数:1838 字
阅读完需:约 6 分钟
概述
《集合-Java-笛卡尔积、平铺》本文是关于对集合进行笛卡尔积操作、平铺操作的示例,技术层面并不复杂,故不过多进行介绍。
背景
笛卡尔积: 每个业务键有多个值,把所有值的集合都计算出来。可以类比关系型数据库的关联查询。
平铺: 每个业务键有多个值,把所有值的集合都计算出来,并区分当前选择的是哪个业务键。
实现
递归实现笛卡尔积,如下代码可以直接执行。
public void test() { List<List<String>> strList = new ArrayList<>(); for(int i = 1; i <= 2; i++) { List<String> partStrList = new ArrayList<>(); for(int j = 1; j <= 2; j++) { partStrList.add("(" + (i + "") + (j + "") + ")"); } strList.add(partStrList); }
List<String> descartesList = descartes(strList, 0, StringUtils.EMPTY, new ArrayList<>()); // [(11)(21), (11)(22), (12)(21), (12)(22)] }
public static List<String> descartes(List<List<String>> dimensionValues, int position, String originCode, List<String> result) { // 获取指定行数据 List<String> rowValue = dimensionValues.get(position); for (String code : rowValue) { // 第一行不用拼接,直接copy,第二行开始需要在末尾拼接code String resultCode = position == 0 ? code : originCode + code; // 如果当前位置是最后一行,则可以添加最终resultCode构建结果 if (position == dimensionValues.size() - 1) { result.add(resultCode); } else { // 否则进入下一行 descartes(dimensionValues, position + 1, resultCode, result); } } return result; }
复制代码
由于实际应用场景中,在数据转平铺的过程中,有时候需要记录数据值对应的是哪个业务键,故增加如下的工具类。
public void test() { Map<String, List<String>> inputMap = new LinkedHashMap<>();
List<String> key1List = Arrays.asList(new String[]{"00001"}); inputMap.put("key1", key1List);
List<String> key2List = Arrays.asList(new String[]{"00001", "00002"}); inputMap.put("key2", key2List);
List<String> key3List = Arrays.asList(new String[]{"00001", "00002", "00003"}); inputMap.put("key3", key3List);
List<Map<String, String>> flatList = flatMap(inputMap); // [{key1=00001, key2=00001, key3=00001}, {key1=00001, key2=00002, key3=00001}, {key1=00001, key2=00001, key3=00002}, {key1=00001, key2=00002, key3=00002}, {key1=00001, key2=00001, key3=00003}, {key1=00001, key2=00002, key3=00003}] }
public static List<Map<String, String>> flatMap(Map<String, List<String>> inputMap) { // 类似笛卡尔积的操作,转平铺 List<Map<String, String>> flatList = new ArrayList<>(); // 使用Stream进行转换 inputMap.forEach((key, values) -> { List<Map<String, String>> intermediateList = new ArrayList<>();
// 为每个值创建一个新的Map,并与之前的结果进行笛卡尔积 values.forEach(value -> { if (flatList.isEmpty()) { Map<String, String> newMap = new HashMap<>(); newMap.put(key, value); intermediateList.add(newMap); } else { flatList.forEach(existingMap -> { Map<String, String> newMap = new HashMap<>(existingMap); newMap.put(key, value); intermediateList.add(newMap); }); } }); flatList.clear(); flatList.addAll(intermediateList); }); return flatList; }
复制代码
参考
划线
评论
复制
发布于: 刚刚阅读数: 5
版权声明: 本文为 InfoQ 作者【alexgaoyh】的原创文章。
原文链接:【http://xie.infoq.cn/article/f2ca28db8ea41fd4b0cdca0f7】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
alexgaoyh
关注
DevOps 2013-12-08 加入
https://gitee.com/alexgaoyh







评论