数仓中的JSON串困扰了我,格式化Object转为 List 到底有多坑

数仓中的JSON串困扰了我,格式化Object转为 List 到底有多坑

曾经年少爱追梦,一心只想往前飞。

最近在做报表的需求,中间数仓表存储的是大量的JSON字符串,处理起来真的是太过于繁琐,没有明确的POJO,可能是List<Map<…>>格式,完全是单个key单个key去取值。个人总结下其中的一些场景【Object转为 List】,首先确保 Object 的真实类型是 ArrayList<Pojo>ArrayList<LinkedHashMap>

在 Java 中将 Object 转换为 List 时,具体方式取决于 Object 的实际类型和内容。以下是几种常见的方式:


1. 使用强制类型转换

(前提是明确类型)

如果确定 Object 本身就是一个 List,可以直接进行强制类型转换:

Object obj = Arrays.asList("A", "B", "C");
List<String> list = (List<String>) obj; // 直接转换

注意: 如果 obj 不是 List 类型,直接转换会抛出 ClassCastException


2. 使用 instanceof 检查类型

为避免 ClassCastException,可以使用 instanceof 判断类型:

if (obj instanceof List) {
    List<String> list = (List<String>) obj;
} else {
    throw new IllegalArgumentException("Object is not a List");
}

3. 通过 JSON 序列化和反序列化

(个人推荐这种方式。站在巨人的肩膀上,更容易成功)

如果 Object 实际是 JSON 数据(如 JSONArray 或 JSON 字符串),可以使用 JSON 工具库转换为 List

使用 Jackson:
ObjectMapper objectMapper = new ObjectMapper();
List<String> list = objectMapper.convertValue(obj, new TypeReference<List<String>>() {});
使用 Gson:
Gson gson = new Gson();
List<String> list = gson.fromJson(gson.toJson(obj), new TypeToken<List<String>>() {}.getType());
使用 FastJSON:
List<String> list = JSON.parseArray(JSON.toJSONString(obj), String.class);

4. 手动处理 ArrayList 和其他集合

如果 Object 是某种集合类型(如 ArrayListHashSet),但类型未知,可将其转换为 List

if (obj instanceof Collection) {
    List<Object> list = new ArrayList<>((Collection<?>) obj);
}

5. 通过 Stream API 转换

如果 Object 是数组或其他集合,可以通过 Stream 转换为 List

if (obj instanceof Object[]) {
    List<Object> list = Arrays.stream((Object[]) obj).collect(Collectors.toList());
}

6. 处理 LinkedHashMap 类型的 List

如果 ObjectList<LinkedHashMap> 类型(如通过 JSON 反序列化产生的数据),可以将其进一步转换为目标 POJO:

List<LinkedHashMap<String, Object>> tempList = (List<LinkedHashMap<String, Object>>) obj;
List<MyPojo> pojoList = tempList.stream()
        .map(map -> objectMapper.convertValue(map, MyPojo.class))
        .collect(Collectors.toList());

7. 转换带有泛型的 List

当目标 List 的泛型类型未知时,可以利用通配符或反射动态转换:

Object obj = Arrays.asList("A", "B", "C");
List<?> list = (List<?>) obj; // 使用通配符处理未知泛型

注意事项

  1. 类型安全:确保 Object 的实际类型和目标 List 类型一致。
  2. 避免强制转换异常:使用 instanceof 或 JSON 工具类更安全。
  3. Null 检查:转换前确保 Object 不为 null,或者使用默认值。

根据实际需求选择适合的方式。对于复杂类型的 Object,使用 JSON 工具库往往是最通用的解决方案。

<think>在Qt中,将JSON字符换为对象主要使用`QJsonDocument`、`QJsonObject`等类。以下是详细步骤: ### 步骤1:包含必要的头文件 ```cpp #include <QJsonDocument> #include <QJsonObject> #include <QJsonParseError> ``` ### 步骤2:解析JSON字符 ```cpp QString jsonString = R"({ "name": "张三", "age": 30, "skills": ["C++", "Qt", "Python"] })"; QJsonParseError parseError; QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8(), &parseError); // 检查解析错误 if (parseError.error != QJsonParseError::NoError) { qDebug() << "JSON解析错误:" << parseError.errorString(); return; } ``` ### 步骤3:获取JSON对象 ```cpp QJsonObject jsonObj = jsonDoc.object(); ``` ### 步骤4:从JSON对象中提取据 ```cpp QString name = jsonObj["name"].toString(); int age = jsonObj["age"].toInt(); // 提取组 QJsonArray skillsArray = jsonObj["skills"].toArray(); QStringList skills; for (const QJsonValue &value : skillsArray) { skills << value.toString(); } ``` ### 完整示例代码 ```cpp #include <QCoreApplication> #include <QJsonDocument> #include <QJsonObject> #include <QJsonArray> #include <QJsonParseError> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 示例JSON字符 QString jsonString = R"({ "name": "张三", "age": 30, "isStudent": false, "address": { "city": "北京", "street": "中关村" }, "skills": ["C++", "Qt", "Python"] })"; QJsonParseError parseError; QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8(), &parseError); if (parseError.error != QJsonParseError::NoError) { qDebug() << "JSON解析错误:" << parseError.errorString(); return -1; } if (!jsonDoc.isObject()) { qDebug() << "JSON文档不是对象"; return -1; } QJsonObject jsonObj = jsonDoc.object(); // 提取基本类型 QString name = jsonObj["name"].toString(); int age = jsonObj["age"].toInt(); bool isStudent = jsonObj["isStudent"].toBool(); // 提取嵌套对象 QJsonObject addressObj = jsonObj["address"].toObject(); QString city = addressObj["city"].toString(); QString street = addressObj["street"].toString(); // 提取组 QStringList skills; QJsonArray skillsArray = jsonObj["skills"].toArray(); for (const QJsonValue &value : skillsArray) { skills.append(value.toString()); } // 输出结果 qDebug() << "姓名:" << name; qDebug() << "年龄:" << age; qDebug() << "学生:" << (isStudent ? "是" : "否"); qDebug() << "地址:" << city << street; qDebug() << "技能:" << skills; return a.exec(); } ``` ### 关键点说明: 1. **字符编码**: 使用`toUtf8()`将QString换为UTF-8编码的QByteArray,因为`fromJson()`需要字节组[^1]。 2. **错误处理**: 通过`QJsonParseError`捕获解析错误,如格式错误、缺少引号等[^3]。 3. **类型检查**: - 使用`isObject()`检查文档是否为对象 - 使用`isArray()`检查值是否为组 - 使用`isString()`/`isDouble()`等检查具体类型 4. **嵌套对象处理**: 通过`toObject()`将嵌套的JSON对象换为`QJsonObject`[^1]。 5. **组处理**: 使用`toArray()`将JSON换为`QJsonArray`,然后遍历提取值[^2]。 ### 处理中文的注意事项: - JSON字符中可以直接使用中文,但需确保源文件编码为UTF-8 - 在Qt Creator中:`工具` → `选项` → `文本编辑器` → `行为` → 文件编码设置为UTF-8 ### 项目配置(.pro文件) ```qmake QT += core CONFIG += console SOURCES += main.cpp ``` ### 输出示例: ``` 姓名: "张三" 年龄: 30 学生: 否 地址: "北京" "中关村" 技能: ("C++", "Qt", "Python") ``` §§相关问题§§ 1. 如何将Qt对象换为JSON字符?[^2] 2. 如何处理JSON中的日期时间类型? 3. 如何解析包含特殊字符的JSON字符? 4. Qt中如何验证JSON据的有效性? 5. 如何优化大型JSON文件的解析性能? [^1]: Qt提供了QJsonDocument、QJsonObject等类处理JSON据[1] [^2]: 通过QJsonDocument::toJson()可将对象换为字符[2] [^3]: 使用QJsonParseError捕获解析错误[3]</think>在Qt中将JSON字符换为对象,主要使用`QJsonDocument`、`QJsonObject`和`QJsonParseError`类。以下是详细步骤和示例代码: ### 核心步骤 1. **包含头文件** ```cpp #include <QJsonDocument> #include <QJsonObject> #include <QJsonParseError> ``` 2. **解析JSON字符** ```cpp QString jsonString = R"({ "name": "张三", "age": 30, "isStudent": false, "skills": ["C++", "Qt", "Python"] })"; QJsonParseError parseError; QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8(), &parseError); ``` 3. **检查解析错误** ```cpp if (parseError.error != QJsonParseError::NoError) { qDebug() << "JSON解析错误:" << parseError.errorString(); return; } ``` 4. **获取JSON对象** ```cpp if (!jsonDoc.isObject()) { qDebug() << "JSON文档不是对象"; return; } QJsonObject jsonObj = jsonDoc.object(); ``` 5. **提取据** ```cpp QString name = jsonObj["name"].toString(); int age = jsonObj["age"].toInt(); bool isStudent = jsonObj["isStudent"].toBool(); // 提取组 QJsonArray skillsArray = jsonObj["skills"].toArray(); QStringList skills; for (const QJsonValue &value : skillsArray) { skills.append(value.toString()); } ``` ### 完整示例 ```cpp #include <QCoreApplication> #include <QJsonDocument> #include <QJsonObject> #include <QJsonArray> #include <QJsonParseError> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 1. 定义JSON字符 QString jsonString = R"({ "name": "李四", "age": 25, "isStudent": true, "address": { "city": "北京", "street": "中关村" }, "languages": ["C++", "Java", "Python"] })"; // 2. 解析JSON QJsonParseError parseError; QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8(), &parseError); // 3. 检查错误 if (parseError.error != QJsonParseError::NoError) { qDebug() << "JSON解析错误:" << parseError.errorString(); return -1; } // 4. 获取根对象 QJsonObject rootObj = jsonDoc.object(); // 5. 提取基本据 QString name = rootObj["name"].toString(); int age = rootObj["age"].toInt(); bool isStudent = rootObj["isStudent"].toBool(); // 6. 提取嵌套对象 QJsonObject addressObj = rootObj["address"].toObject(); QString city = addressObj["city"].toString(); QString street = addressObj["street"].toString(); // 7. 提取组 QStringList languages; QJsonArray langArray = rootObj["languages"].toArray(); for (const QJsonValue &val : langArray) { languages << val.toString(); } // 输出结果 qDebug() << "姓名:" << name; qDebug() << "年龄:" << age; qDebug() << "学生:" << (isStudent ? "是" : "否"); qDebug() << "地址:" << city << street; qDebug() << "语言:" << languages; return a.exec(); } ``` ### 关键注意事项 1. **中文处理**: ```cpp // 使用QString直接处理中文,无需特殊换 QString name = jsonObj["name"].toString(); ``` 2. **类型安全**: ```cpp // 检查类型后再换 if (jsonObj["age"].isDouble()) { int age = jsonObj["age"].toInt(); } ``` 3. **错误处理**: - `QJsonParseError` 提供详细的错误信息 - 使用 `contains()` 检查键是否存在: ```cpp if (jsonObj.contains("email")) { QString email = jsonObj["email"].toString(); } ``` 4. **嵌套对象处理**: ```cpp QJsonObject address = jsonObj["address"].toObject(); QString city = address["city"].toString(); ``` ### 输出示例 ``` 姓名: "李四" 年龄: 25 学生: 是 地址: "北京" "中关村" 语言: ("C++", "Java", "Python") ``` ### 项目配置(.pro文件) ```qmake QT += core CONFIG += console SOURCES += main.cpp ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值