行业资讯 2025年08月6日
0 收藏 0 点赞 591 浏览 4070 个字
摘要 :

文章目录 1.介绍 2.使用Jackson 2.1. 使用ObjectMapper.convertValue() 2.2. 使用JavaPropsMapper将其转换为Properties 3.使用Gson的TypeToken 4.使用反射 5.结论 本……




  • 1.介绍
  • 2.使用Jackson
    • 2.1. 使用ObjectMapper.convertValue()
    • 2.2. 使用JavaPropsMapper将其转换为Properties
  • 3.使用Gson的TypeToken
  • 4.使用反射
  • 5.结论

本教程将教您如何使用Jackson和Gson API提供的不同方式将对象转换为Java Map。您还可以使用Java反射创建自己的解决方案,除非提供的解决方案不适用时,否则不建议重新造轮子。

1.介绍

在本教程中,我们将把以下Employee类的实例转换为Map。Employee类包含简单类型,如String,以及新的Java类型,如LocalDate和集合类型。

我们有一个Role类型的List,以进一步演示不同解决方案的行为。我们将看到不同的解决方案如何将转换后的Map中的嵌套类型进行转换。

class Employee {
  private Integer id;
  private String name;
  private LocalDate dateOfBirth;
  private List<String> locations;
  private List<Role> roles;
}
class Role {
  private Integer id;
  private String name;
}

2.使用Jackson

Jackson是一个多用途的库,非常好地支持不同类型的转换,如JSON或XML。Jackson还支持使用以下方式将对象转换为Map:

2.1. 使用ObjectMapper.convertValue()

convertValue()方法从给定值转换为给定值类型的实例进行两步转换。它首先将给定值序列化为JSON,然后将JSON数据绑定到给定类型的值上。但由于不需要进行完全序列化,所以转换更加高效。

请注意,在以下示例中,我们正在注册JavaTimeModule类,因为Jackson默认不支持新的Java 8日期时间类。

Employee employee = new Employee(1, \"Alex\",
        LocalDate.of(1995, 1, 2),
        List.of(\"Delhi\", \"Nevada\"),
        List.of(new Role(11, \"Finance\"), new Role(12, \"HR\")));
System.out.println(convertObjectToMapUsingObjectMapper(employee));
//转换方法
static Map<String, String> convertObjectToMapUsingObjectMapper(Employee employee) {
  ObjectMapper objectMapper = new ObjectMapper();
  objectMapper.registerModule(new JavaTimeModule());
  objectMapper.setDateFormat(new SimpleDateFormat(\"yyyy-MM-dd\"));
  return objectMapper.convertValue(employee, Map.class);
}

输出:

{
    id=1,
    name=Alex,
    dateOfBirth=1995-01-02,
    locations=[Delhi, Nevada],
    roles=[
        {id=11, name=Finance},
        {id=12, name=HR}
    ]
}

请注意,此方法还将关联和嵌套类(例如Role)转换为LinkedHashMap。

2.2. 使用JavaPropsMapper将其转换为Properties

另一种有趣的解决方案是将对象转换为Properties。Properties具有扁平结构。即使嵌套结构和集合也会转换为扁平结构,所有字段/值都会转换为字符串。在某些情况下,这可能是一个不错的解决方案。

Employee employee = new Employee(1, \"Alex\",
        LocalDate.of(1995, 1, 2),
        List.of(\"Delhi\", \"Nevada\"),
        List.of(new Role(11, \"Finance\"), new Role(12, \"HR\")));
System.out.println(convertObjectToMapUsingJavaPropsMapper(employee));
//转换方法
static Properties convertObjectToMapUsingJavaPropsMapper(Employee employee) throws IOException {
  JavaPropsMapper mapper = new JavaPropsMapper();
  mapper.registerModule(new JavaTimeModule());
  mapper.setDateFormat(new SimpleDateFormat(\"yyyy-MM-dd\"));
  Properties properties = mapper.writeValueAsProperties(employee);
  return properties;
}

输出:

{
    id=1,
    name=Alex,
    dateOfBirth=1995-01-02,
    locations.1=Delhi,
    locations.2=Nevada,
    roles.1.id=11,
    roles.1.name=Finance,
    roles.2.id=12,
    roles.2.name=HR
}

3.使用Gson的TypeToken

如果我们的项目已经在应用程序中具有Gson依赖项,我们可以考虑使用Gson.fromJson()将对象转换为JSON,然后在第二步中将JSON转换为HashMap。

这种技术使用完全的序列化和反序列化,因此性能可能不如Jackson。如果由于某种原因无法使用Jackson,那么可以考虑使用Gson。

Employee employee = new Employee(1, \"Alex\",
        LocalDate.of(1995, 1, 2),
        List.of(\"Delhi\", \"Nevada\"),
        List.of(new Role(11, \"Finance\"), new Role(12, \"HR\")));
System.out.println(convertObjectToMapUsingGson(employee));
static Map<String, String> convertObjectToMapUsingGson(Employee employee) {
  Gson gson = new GsonBuilder()
      .registerTypeAdapter(LocalDate.class, new LocalDateAdapter())
      .create();
  return gson.fromJson(gson.toJson(employee),
      new TypeToken<HashMap<String, Object>>() {
      }.getType()
  );
}

程序输出:

{
    id=1.0,
    name=Alex,
    dateOfBirth=1995-01-02,
    locations=[Delhi, Nevada],
    roles=[
        {id=11.0, name=Finance},
        {id=12.0, name=HR}
    ]
}

Gson和Jackson之间主要有两个差异:

  • Gson默认将所有数值转换为Double类型。
  • Gson在嵌套类中使用LinkedTreeMap,而Jackson使用LinkedHashMap。

4.使用反射

另一种可能的方法,尽管不建议使用,是使用反射。使用反射,我们必须自己编写所有逻辑,因此存在出错的机会。如果采用这种方法,请确保在部署到生产环境之前进行充分测试。

以下是一个用于简单POJO类的非常基本的代码片段,它依赖于按名称获取字段的值。如果有这样的要求,我们可以调整方法以通过其getter获取值。

public static Map<String, Object> toKeyValuePairs(Object instance) {

  return Arrays.stream(Employee.class.getDeclaredFields())
      .collect(Collectors.toMap(
          Field::getName,
          field -> {
            try {
              Object result = null;
              field.setAccessible(true);
              result = field.get(instance);
              return result != null ? result : \"\";
            } catch (Exception e) {
              return \"\";
            }
          }));
}

程序输出:

{
    id=1,
    name=Alex,
    dateOfBirth=1995-01-02,
    locations=[Delhi, Nevada],
    roles=[
        Role(id=11, name=Finance),
        Role(id=12, name=HR)
    ]
}

我们可以发现Map结构保持了嵌套类的原样,因为我们没有访问它们或在我们的逻辑中处理它们。如果需要在应用程序中处理它们,那么请进一步扩展toKeyValuePairs()方法中的逻辑。

5.结论

这个Java教程教会了我们如何使用不同的解决方案将给定的Java对象转换为Map。通过查看所有解决方案,从易用性和性能的角度来看,Jackson似乎是最佳解决方案,并在大多数情况下是推荐的方法。

对于创建扁平结构,我们可以使用JavaPropsMapper将对象转换为Properties。

使用Gson与Jackson非常相似,但它没有提供任何额外的优势,而所有数字都被转换为Double,这在某些情况下可能不是一个理想的情况。因此,当无法使用Jackson时使用Gson。

最后,反射可以完全掌握在您手中,您必须自己编写每种可能的用例/条件。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/9381.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号