Java实现递归将嵌套Map里的字段名由驼峰转为下划线

摘要: 使用Java语言递归地将Map里的字段名由驼峰转下划线。通过此例可以学习如何递归地解析任意嵌套的List-Map容器结构。

难度:初级

概述

在进行多语言混合编程时,由于编程规范的不同, 有时会需要进行字段名的驼峰-下划线转换。比如 php 语言中,变量偏向于使用下划线,而Java 语言中,变量偏向于驼峰式。当 PHP 调用 java 接口时,就需要将 java 返回数据结构中的驼峰式的字段名称改为下划线。使用 jackson 解析 json 数据时,如果不指定解析的类,常常会将 json 数据转化为 LinkedHashMap 。 因此,需要将 LinkedHashMap 里的字段名由驼峰转为下划线。

这里的难点是, Map 结构可能是非常复杂的嵌套结构,一个 Map 的某个 key 对应的 value 可能是原子的,比如字符串,整数等,可能是嵌套的 Map, 也可能是含有多个 Map 的 List , 而 map , list 内部又可能嵌套任意的 map 或 list . 因此,要使用递归的算法来将 value 里的 key 递归地转化为下划线。

算法设计

首先,要编写一个基本函数 camelToUnderline,将一个字符串的值从驼峰转下划线。这个函数不难,逐字符处理,遇到大写字母就转成 _ + 小写字母 ; 或者使用正则表达式替换亦可;

其次,需要使用基本函数 camelToUnderline 对可能多层嵌套的 Map 结构进行转化。

假设有一个函数 transferKeysFromCamelToUnderline(amap) , 可以将 amap 里的所有 key 从驼峰转化为下划线,包括 amap 里嵌套的任意 map。返回结果是 resultMap ;

(1) 首先考虑最简单的情况:没有任何嵌套的情况,原子类型的 key 对应原子类型的 value ; resultMap.put(newkey, value) 即可 , newkey = camelToUnderline(key);

(2) 其次考虑 Map 含有嵌套 subMap 的情况: 假设 <key, value> 中,value 是一个 subMap, 那么,调用 camelToUnderline(key) 可以得到新的 newkey ,调用 transferKeysFromCamelToUnderline(subMap) 就得到转换了的 newValue , 得到 <newkey, newValue>; resultMap.put(newkey, newValue)

(3) 其次考虑 Map 含有 List 的情况: List 里通常含有多个 subMap , 只要遍历里面的 subMap 进行转换并添加到新的 List, 里面含有所有转换了的 newValue = map(transferKeysFromCamelToUnderline, List[subMap]); resultMap.put(newkey, newValue) .

递归技巧

当使用递归方式思考的时候,有三个技巧值得注意:

(1) 首先,一定从最简单的情况开始思考。 这是基础,也是递归终结条件;

(2) 其次,要善于从语义上去理解,而不是从细节上。 比如说 Map 含有嵌套 subMap 的时候, 就不要细想 subMap 里面是怎样复杂的结构,是单纯的一个子 map ,还是含有 List 的 Map 的 Map 的 Map; 这样想会Feng掉滴^_^ 只需要知道 transferKeysFromCamelToUnderline(amap) 能够对任意复杂结构的 amap 进行转换得到所有 key 转换了的 resultMap , 而在主流程中直接使用这个 subResultMap 即可。这个技巧值得多体会多训练下才能掌握。

(3) 结果的存放。 既可以放在参数里,在递归调用的过程中逐步添加完善,也可以放在返回结果中。代码实现中展示了两种的用法。从某种意义来说,递归特别需要仔细地设计接口 transferKeysFromCamelToUnderline ,并从接口的语义上去理解和递归使用。

代码实现

/**
 * Created by shuqin on 16/11/3.
 * Improved by shuqin on 17/12/31.
 */
package zzz.study.datastructure.map;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值