如何在不改变键序的前提下递归更新嵌套对象中的所有字符串值

阿枫大大_9733

阿枫大大_9733

2026-05-10

534人浏览

原创

如何在不改变键序的前提下递归更新嵌套对象中的所有字符串值

本文介绍一种基于深度优先遍历的通用方法,使用 LinkedHashMap 保持 JSON-like 对象的字段顺序,递归更新任意深度嵌套结构中所有字符串值(如追加后缀),同时避免重建原始对象引用之外的冗余副本。

本文介绍一种基于深度优先遍历的通用方法,使用 `linkedhashmap` 保持 json-like 对象的字段顺序,递归更新任意深度嵌套结构中所有字符串值(如追加后缀),同时避免重建原始对象引用之外的冗余副本。

在处理复杂嵌套数据结构(如类 JSON 的 Map/Array 混合对象)时,若需原语义顺序不变地批量修改字符串值(例如统一追加 " Hello"),关键挑战在于:既要保证递归遍历的完整性,又要严格维持原始对象中键的插入顺序(Java 中 HashMap 不保证顺序,而 LinkedHashMap 可以)。原始实现使用 HashMap 导致顺序丢失,且未覆盖 List、Number 等常见类型,存在兼容性与健壮性缺陷。

以下是一个生产就绪的改进方案,支持 String、Map(自动选用 LinkedHashMap)、Object[]、List 及基础原子类型,并保留全部嵌套层级的原始结构顺序:

import java.util.*;

public class ObjectStringUpdater {

    public static Object updateStrings(Object obj, String suffix) {
        if (obj == null) return null;
        if (obj instanceof String) {
            return ((String) obj) + suffix;
        } else if (obj instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<object object> map = (Map<object object>) obj;
            Map<object object> updatedMap = new LinkedHashMap(map.size());
            for (Map.Entry<object object> entry : map.entrySet()) {
                updatedMap.put(entry.getKey(), updateStrings(entry.getValue(), suffix));
            }
            return updatedMap;
        } else if (obj instanceof List) {
            @SuppressWarnings("unchecked")
            List<object> list = (List<object>) obj;
            List<object> updatedList = new ArrayList(list.size());
            for (Object item : list) {
                updatedList.add(updateStrings(item, suffix));
            }
            return updatedList;
        } else if (obj instanceof Object[]) {
            Object[] arr = (Object[]) obj;
            Object[] updatedArr = new Object[arr.length];
            for (int i = 0; i <p>✅ <strong>核心优化点说明:</strong>  </p>
<ul>
<li>使用 LinkedHashMap 替代 HashMap,确保 map 键值对按插入顺序迭代,完美保留 "name" → "age" → "height" → "body" 等原始字段顺序;  </li>
<li>显式支持 List(如 ArrayList、LinkedList),避免因 instanceof Collection 模糊判断导致的遗漏;  </li>
<li>对 null 值做防御性检查,防止 NullPointerException;  </li>
<li>所有非字符串、非容器类型(如 Integer、Double、Boolean)原样透传,不强制转换或误处理;  </li>
<li>方法设计为纯函数式(无副作用),返回全新结构,但内部复用原始不可变值(如数字、布尔),内存友好。</li>
</ul>
<p>? <strong>调用示例:</strong>  </p>
<pre class="brush:php;toolbar:false;">// 构建示例嵌套对象(注意:实际中可能来自 Jackson/YAML 解析)
Map<string object> root = new LinkedHashMap();
root.put("name", "name");
root.put("age", 12);
root.put("height", 1.50);
Map<string object> body = new LinkedHashMap();
body.put("detail1", "detail1");
body.put("detail2", "detail2");
body.put("detail3", "detail3");
body.put("detail4", Arrays.asList("detail4", ""));
root.put("body", body);
root.put("arr", Arrays.asList(1, 2, 3));
root.put("arr2", Arrays.asList("", "", ""));
Map<string object> bod2 = new LinkedHashMap();
Map<string object> child = new LinkedHashMap();
child.put("name", "a");
child.put("name2", "b");
bod2.put("child", child);
root.put("bod2", bod2);

// 执行更新
Object result = ObjectStringUpdater.updateStrings(root, " Hello");
System.out.println(result); // 输出符合预期:所有字符串已追加,且键序、嵌套结构完全一致</string></string></string></string>

⚠️ 注意事项:

  • 该方法不修改原始对象,而是生成新结构——这是安全实践,避免意外共享状态;若需就地修改(极少数场景),应额外设计可变容器接口,但会显著增加复杂度与风险;
  • 若输入含自定义 POJO 类型(非 Map/List),默认跳过;如需支持,可扩展为检查 getDeclaredFields() 并反射遍历,但需权衡性能与灵活性;
  • 在高频调用场景中,可考虑将 suffix 预编译为 Function 提升扩展性。

通过此方案,你可在零侵入、零顺序破坏的前提下,精准、高效、可维护地完成任意深度嵌套对象的字符串批量增强操作。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1758

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2744

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6104

49

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2023.11.24

5749

6

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

2024.03.22

7414

16

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2024.04.29

10874

11

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

2025.07.29

5579

17

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.07

6067

13

常用字符串方法大全
常用字符串方法大全

常用字符串方法大全

2025.08.08

3068

14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.9万人学习