使用 Gson 或 Jackson 压平 JSON 字符串,将包含各个级别键值的键制作为 Map

2023-12-10

我有一个关于以下问题的增强问题使用 Gson 或 Jackson 将 JSON 字符串展平为 Map.

我的场景包括重复的键,因此上述问题中的解决方案会导致一些重复的键被覆盖。所以我正在考虑通过将每个级别的密钥组合在一起来构造密钥。

那么如何实现呢?

例如:

{
    "id" : "123",
    "name" : "Tom",
    "class" : {
        "subject" : "Math",
        "teacher" : "Jack"
    }
}

我想获取地图:

"id" : "123",
"name" : "Tom",
"class.subject" : "Math",
"class.teacher" : "Jack"

**********************更新解决方案************************ **************

根据@Manos Nikolaidis的回答,我能够通过考虑ArrayNode来实现以下解决方案。

public void processJsonString(String jsonString) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    ArrayNode arrayNode = (ArrayNode) mapper.readTree(jsonString);
    processArrayNode(arrayNode);
}

private void processObjectNode(JsonNode jsonNode) {
    Map<String, String> result = new HashMap<>();
    Iterator<Map.Entry<String, JsonNode>> iterator = jsonNode.fields();
    iterator.forEachRemaining(node -> mapAppender(result, node, new ArrayList<String>()));
}

private void processArrayNode(ArrayNode arrayNode) {
    for (JsonNode jsonNode : arrayNode) {
        processObjectNode(jsonNode);
    }
}


private void mapAppender(Map<String, String> result, Map.Entry<String, JsonNode> node, List<String> names) {
    names.add(node.getKey());
    if (node.getValue().isTextual()) {
        String name = names.stream().collect(Collectors.joining("."));
        result.put(name, node.getValue().asText());
    } else if (node.getValue().isArray()) {
        processArrayNode((ArrayNode) node.getValue());
    } else if (node.getValue().isNull()) {
        String name = names.stream().collect(Collectors.joining("."));
        result.put(name, null);
    } else {
        node.getValue().fields()
                        .forEachRemaining(nested -> mapAppender(result, nested, new ArrayList<>(names)));
    }
}

您可以将 JSON 获取为JsonNode并递归地遍历所有字段并将键和值字段添加到 Map 中。当值是对象而不是字符串时,您可以将字段名称添加到列表中,以便在最终遇到字符串时与句点连接。首先创建(为了可读性)一个单独的方法,将 Json 字段添加到Map:

void mapAppender(Map<String, String> result, Entry<String, JsonNode> node, List<String> names) {
    names.add(node.getKey());
    if (node.getValue().isTextual()) {
        String name = names.stream().collect(joining("."));
        result.put(name, node.getValue().asText());
    } else {
        node.getValue().fields()
            .forEachRemaining(nested -> mapAppender(result, nested, new ArrayList<>(names)));
    }
}

并像这样使用它:

ObjectMapper mapper = new ObjectMapper();
Map<String, String> result = new HashMap<>();
mapper.readTree(json).fields()
    .forEachRemaining(node -> mapAppender(result, node, new ArrayList<String>()));

Where fields()返回一个Iterator。提防StackOverflowErrors深度嵌套的 JSON 的性能可能较低。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Gson 或 Jackson 压平 JSON 字符串,将包含各个级别键值的键制作为 Map 的相关文章

  • Oracle/PHP - ORA-00911 更新时的无效字符

    我正在运行一个 PHP 脚本 该脚本从 Oracle 数据库实例更新表 首先 我收到一个 JSON 对象 lot KLMHA17N9N00 requestor B10078 id FRESHLOT username B26696 passw
  • cucumber.json 报告被重新运行场景报告覆盖

    我有一个具有相同技术堆栈 JAVA1 8 Cucumber JVM JUnit Maven 的 UI 测试项目和一个 API 测试项目 这两个项目都向我展示了这个问题 可能是因为两者都存在相同的依赖关系集 我使用了使用 maven sure
  • 解析错误:第 2 行第 0 列的数字文字无效

    我正在尝试读取一个大的 json 数据结构 我收到消息 解析错误 第 2 行第 0 列的数字文字无效 我正在使用的命令是下一个 n rules echo rulebase list jq total 该文件在第一层次结构中具有一个变量 该变
  • 对 Java Servlet 进行单元测试

    我想知道对 servlet 进行单元测试的最佳方法是什么 只要内部方法不引用 servlet 上下文 测试内部方法就不是问题 但是测试 doGet doPost 方法以及引用上下文或使用会话参数的内部方法呢 有没有办法简单地使用经典工具 例
  • 无法解析 ListView 适配器中的 getSystemService 方法

    我正在研究约翰霍顿的Android 编程初学者 目前正在尝试创建一个笔记应用程序 霍顿刚刚介绍ListViews 但是 我遇到了麻烦adapter class public class NoteAdapter extends BaseAda
  • 要导入什么才能使用@SuppressFBWarnings?

    要使用 SuppressFBWarnings 需要导入什么 我通过帮助 安装新软件安装了 findbugs 插件 当我输入 import edu 时 我无法按 ctrl space 来获取选项 Example try String t nu
  • 结果显示图像上有衬里

    我正在使用 opencv 和 android ndk 下面是我的 jni 代码 void Vignete Mat img1 Mat img2 Mat out resize img1 img1 img2 size img1 convertTo
  • ImageIO read() 和 write() 操作后 GIF 图像变得错误

    我有这个代码 它只是读取 GIF 文件 用背景重新绘制它 然后输出到新的 GIF 文件 问题是结果文件变得奇怪 我不知道为什么它的质量变得很差 JPG 文件不会出现此问题 如何修复它 import java awt Color import
  • Java JDT 解析器。获取VariableDeclarationFragment的变量类型

    我一直在用 JDT 实现 Java 解析器 但我不知道当变量的节点类型为变量声明片段 我只有在涉及到时才发现如何获取变量类型变量声明 我的代码如下 public boolean visit VariableDeclarationFragme
  • 有没有办法使用 SauceLabs 的 RemoteWebDriver 禁用 CORS 检查

    问题说明了一切 我正在尝试在 SauceLabs 上执行一些硒测试 该测试加载一个发出跨域请求的网页 我在想是否有一种方法可以通过代码以独立于平台的方式禁用 CORS 使用时Chrome驱动程序 Chrome组合禁用cors questio
  • 用于计算句子中单词数的正则表达式

    public static int getWordCount String sentence return sentence split a zA Z0 9 a zA Z0 9 1 length sentence replaceAll a
  • Eclipse 错误:“设置构建路径”遇到错误

    我正在使用一个名为 jtwitter 的 API 它有一个 jar 文件 jtwitter jar 我一直在使用它并使用 git 维护它 我把代码托管在github上 有些天 我没有碰过它的代码 今天 当我克隆我的 git repo 时 实
  • Guice 字段注入不起作用(返回 null)

    我在使用 Guice 时遇到空值问题 接下来我将向您展示一个类似场景的示例 我知道字段注入是一种不好的做法 但我希望它在演示中像这样工作 我有一个名为B 这是我要注入的 class B Inject public B public void
  • 通过命令行参数更改默认的 ant 目标

    最近我被分配了一个任务 让ant能够为不同的环境构建war包 除了一项功能外 我几乎完成了 蚂蚁接受一个env参数类似 Denv DEV 并使用不同的配置文件来制作war包 但默认目标是start它将构建 部署并启动 tomcat 我不希望
  • Tomcat 与 Weblogic JNDI 查找

    我们使用的 Weblogic 服务器已配置为允许 JNDI 数据源名称 例如 appds 对于开发 本地主机 我们可能会运行 Tomcat 并且在 server xml 的 部分中声明时 Tomcat 会将 JNDI 数据源挂在 JNDI
  • C中使用JNI从对象获取对象

    public class Student private People people private Result result private int amount 这是 Java 中类的示例 在C中 我试图获取 学生 中的 人 但失败了
  • 为什么永久代空间不断增长?

    我读过几篇文章 我理解以下内容 如果我错了 请纠正我和 或编辑问题 java堆是这样分段的 年轻代 创建的对象放在这里 这部分被频繁且廉价地垃圾收集 老一代 在年轻代的垃圾收集中幸存下来的对象会移到此处 该区域的垃圾收集频率较低 并且使用对
  • Java中精确的时间测量

    Java 提供了两种获取当前时间的方法 System nanoTime and System currentTimeMillis 第一个给出的结果以纳秒为单位 但实际精度比这要差得多 许多微秒 JVM 是否已经为每台特定机器提供了最佳的价值
  • 如何使用属性文件在log4j2中创建多个日志文件?

    我正在使用 property 文件在特定路径中创建日志文件 但我正在使用它创建单个文件 以下是我的属性文件代码 status error dest err name PropertiesConfig property filepath ap
  • 获取给定字符串日期中该月的最后一天

    我的输入字符串日期如下 String date 1 13 2012 我得到的月份如下 SimpleDateFormat dateFormat new SimpleDateFormat MM dd yyyy Date convertedDat

随机推荐

  • 如何通过 Symfony 4 连接到使用 MAMP 创建的 mySQL 数据库?

    我在 MAMP 中创建了一个名为 project 的数据库 In my env文件我添加了这一行 DATABASE URL mysql root root localhost 3306 project 现在我想跑 php bin conso
  • R markdown / bookdown - 如何在摘要下方显示关键字?

    我在 Rmd 文件中定义了关键字 但它们在输出 PDF 中不可见 电流输出 预期成绩 当前 Rmd Rmd 文件的第一行如下所示 title No keywords within the output file abstract This
  • 快速计算大浮点数,例如 0.4 ^ 100000000 , 有什么想法吗?

    嗯 我有一个问题 我有一个特定的计算 结果超过 10 308 double net 中的最大值 无论如何我通过一个名为 BIGFLOAT 的库解决了这个问题http www fractal landscapes co uk bigint h
  • 在 IBM Worklight 推送通知中使用轮询时出现问题

    我正在使用 Android 设备尝试 WL 6 0 推送通知 推送通知工作正常 我也尝试过使用轮询 根据信息中心的文档 对于轮询 我们需要调用另一个过程 并在一定时间间隔后 当我们从该过程获得响应时 方法推送完成 如果我错了 请纠正我 因此
  • Java继承示例

    下面是继承的例子 class Parent Parent int a int b int c a b System out println Sum c void display System out println Return State
  • 如何在 iOS 中的 MKAnnotation 中添加更多详细信息

    我想在 MKAnnotation 中添加更多详细信息 例如位置标题 描述 日期 位置名称 因此需要四行 但我发现只有 2 个参数可以传递给 MKAnnotation 即标题和副标题 如何在地图上添加更多详细信息 请帮助我 提前致谢 看一下创
  • 实例化不可变的配对对象

    是否可以创建一个具有对合作伙伴对象的不可变引用的类 或者它必须是一个var我在创建后分配的 e g class PairedObject p PairedObject id String val partner PairedObject p
  • 无法在 Eclipse 中找到混淆的 Firebase 类

    是的 遗憾的是我正在开发一个仍在使用 Eclipse 进行的项目 我正在将其与 Firebase 集成 并且我阅读了有关使用 Eclipse 获取 aar 文件的内容 如何在 Eclipse 项目中使用 Firebase 云消息 除了以下情
  • 给定一个 x,y 坐标,我需要找到它下面的所有 html 元素

    我正在构建一个应用程序 我反复需要获取位于特定位置 例如相对于视口的 x y 下的 html 元素列表 我正在考虑以下方法 但没有一个令人满意 1 浏览 html 构建一个数据结构来跟踪每个元素的 x y 位置 x y gt 元素集 然后在
  • iOS 8 图像缩放和自动布局

    假设我有一个UIView只有一张图像位于顶部的中心UIView 我为图像提供了图像资源 如下所示 iPhone 4s 及更早版本 50x50 为正常 2x 适用于 iPhone 5 5c 5s 6 100x100 3x 适用于 iPhone
  • Scala泛型类支持多参数功能

    假设我有以下 Foo 类 它使用元组技巧支持任意数量的函数 abstract class Foo T R def pull T gt R 我可以使用以下语法定义子类 implicit def function2Tofunction1 T1
  • 拨号 tcp:不匹配的本地地址类型 172.29.4.175

    我使用以下代码收到此错误 拨号 tcp 不匹配的本地地址类型 172 29 4 175 知道如何解决这个问题吗 除了网上找不到任何有用的东西http oocms org question 763660 dial with a specifi
  • 添加 FirebaseUI 库和支持库时清单合并失败

    我正在使用 google firebase 实施身份验证 我收到此错误 如果可能的话 请有人提出解决方案并附上解释 以便我能理解 错误 任务 app processDebugManifest 执行失败 清单合并失败 来自 com andro
  • 在 R 中按 colSums 划分列

    我正在尝试缩放矩阵中的值 以便每一列加起来为一 我努力了 m matrix c 1 9 nrow 3 ncol 3 byrow T 1 2 3 1 1 2 3 2 4 5 6 3 7 8 9 colSums m 12 15 18 m m c
  • Redshift UDF逻辑问题

    我正在尝试编写 redshift udf 来验证时间戳 但是 它总是返回 false 有人可以解释一下为什么吗 create or replace function f Is timestamp sql VARCHAR 20000 retu
  • 如何使用 Interop 与 C# 将 *.ppt、*.pptx 文件另存为 *.wmv?

    我尝试用下面的代码来做到这一点 using Microsoft Office Core using PowerPoint Microsoft Office Interop PowerPoint using System IO using M
  • 如何使用 Java SDK 获取 AWS Quicksight 仪表板的嵌入 URL

    我想我了解获取 AWS Quicksight 仪表板的嵌入 URL 所需的所有步骤 并且我已经能够通过 AWS CLI 获取有效的 URL 如AWS docs 但是 我似乎无法通过 AWS Java SDK 特别是 v2 让它工作 似乎任何
  • 如何让Android应用程序在屏幕休眠时在后台运行?

    我正在开发一个跟踪应用程序 它通过每 3 秒获取用户当前位置来跟踪用户 当屏幕打开时 我能够获取经纬度值 但当屏幕休眠时 我无法获取数据 CODE Override public void onLocationChanged Locatio
  • 在VS 2017、MVC中添加服务引用

    如何在 VS 2017 MVC 中添加服务引用 我尝试找到 添加服务引用 按钮 但它不在那里 只有 添加引用 和 添加连接的服务 我之前在 VS 2013 中添加了服务引用 这很容易 但现在我为我的学校项目更改为 VS 2017 我不知道如
  • 使用 Gson 或 Jackson 压平 JSON 字符串,将包含各个级别键值的键制作为 Map

    我有一个关于以下问题的增强问题使用 Gson 或 Jackson 将 JSON 字符串展平为 Map 我的场景包括重复的键 因此上述问题中的解决方案会导致一些重复的键被覆盖 所以我正在考虑通过将每个级别的密钥组合在一起来构造密钥 那么如何实