java中常见的对象转换工具

前言

我们在写搬砖的过程中,少不了需要将A对象转成B对象,对对象进行对象的转换是一个操作重复且繁琐的工作。于是市面上就有许多的对象转换工具来解决这个问题,下面我们就来看看几个比较常用的工具(mapstruct,Spring BeanUtils,Apache BeanUtils)使用方式及其性能 。

用法介绍

mapstruct

mapstruct基于注解+字节码生成的方式使用和运行。其支持的功能全面,运行时速度也很快(直接生成转换器类字节码)。示例如下:

maven依赖

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.4.2.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.4.2.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.4.2.Final</version>
    <scope>provided</scope>
</dependency>
复制代码
  1. mapstruct:MapStruct的核心库,包含了MapStruct的基本功能和API。
  2. mapstruct-jdk8:MapStruct的扩展库,包含了对Java 8新特性的支持,例如对LocalDate、LocalTime、LocalDateTime等类型的映射。
  3. mapstruct-processor:MapStruct的注解处理器,用于在编译时生成映射代码。

使用介绍

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    @Mapping(source = "name", target = "fullName")
    UserVO toUserVO(User user);

    List<UserVO> toUserVOs(List<User> users);
}

@Data
public static class UserVO {
    private String fullName;
    private int    age;
}

@Data
public static class User {
    private String name;
    private int    age;
}

// 使用
UserVO userVO = UserMapper.INSTANCE.toUserVO(new User("", ""));
List<UserVO> userVOs = UserMapper.INSTANCE.toUserVOs(users);
复制代码

如示例所示,

  1. 我们只需要定义一个转换器接口,并标记注解@Mapper 。
  2. UserMapper INSTANCE 添加一个调用单例对象。
  3. UserVO toUserVO(User user); 书写转换方法,当两者的属性名称不一致时,可以添加@Mapping 注解来配置对应关系。
  4. 其也可以支持列表的转换,这可以说是相当的方便了。
  5. 查看反编译的源码,可以看到他对null是有检测了,我们也不怕转换的过程中出现空指针异常了。
  6. @Mapping(target = "creationDate", expression = "java(new java.util.Date())") 。我们可以这样,去给一个对象设置默认值。
  7. UserVO toUserVO(User user, Dep dep); 我们还可以将多个对象的值同时拷贝赋值到一个对象中。原理和单对象复制一样。

多源示例代码:

@Mapping(source = "person.description", target = "description")
@Mapping(source = "address.houseNo", target = "houseNumber")
DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address);
复制代码

插件工具

我们可以在idea的插件市场搜索 【MapStruct support】插件,可以增强MapStruct的使用体验。

Spring BeanUtils

Spring BeanUtils使用简单,其有几下几个特点:

  1. 支持类型转换:BeanUtils可以自动将源对象属性的类型转换为目标对象属性的类型,例如将字符串类型的属性值转换为整数类型。
  2. 支持批量复制:BeanUtils可以同时复制多个JavaBean对象的属性,从而简化复制操作。
  3. 支持忽略属性:BeanUtils可以忽略某些属性的复制,从而减少不必要的复制操作。
  4. 为了提高性能,spring缓存了PropertyDescriptor,以提高对象转换的速度。
  5. 不支持属性名称不一致的拷贝,这一点需要注意下,需要拷贝属性了之后,自行处理一下。

示例代码:

org.springframework.beans.BeanUtils.copyProperties(user, userVO);
复制代码

Apache BeanUtils

Apache BeanUtils和Spring BeanUtils使用方式差不多,唯一需要注意的是:Apache BeanUtils的目标类在前面,这一点和Spring BeanUtils正好相反。其特性和Spring BeanUtils差不多。不同点是:

  • 不支持忽略属性配置。
  • 未缓存Class配置,从效率来说,如果复制的对象比较多,效率奇差。从后文的【性能分析】中可以看出。

示例代码:

BeanUtils.copyProperties(userVO, user);
复制代码

性能分析

下面附上mapstruct,Spring BeanUtils,Apache BeanUtils转换对象时时长运行截图:

1条数据下的测试情况:

10条数据下的测试情况:

100条数据下的测试情况:

1000条数据下的测试情况:

10000条数据下的测试情况:

mapstructSpring BeanUtilsApache BeanUtils
12ms198ms53ms
102ms326ms199ms
1003ms277ms1236ms
10004ms636ms5320ms
1000015ms629ms39843ms

从上图中我们可以看出(以上数据仅供参考,更精确的测试可以使用JMH进行)。

  • mapstruct 表现稳定,性能最高,这和它的实现方式有关。

  • Spring BeanUtils 次之,性能也比较稳定,但是小数据量下性能不显著。

  • Apache BeanUtils 最差,性能随着数据量的增长而快速增长。在大数据量下千万别用。

总结

一般我们简单的属性复制用Spring BeanUtils 就可以了,如果数据量比较大或者属性复制的逻辑关系比较复杂,我们可以用mapstruct完成功能。一般不建议使用Apache BeanUtils。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java字符串编码转换工具类可以通过使用Java自带的Charset类和String类的getBytes()方法来实现。下面是一个示例的工具类: ```java import java.nio.charset.Charset; public class EncodingUtils { // 将指定编码的字符串转换为默认编码的字符串 public static String convertToDefaultEncoding(String str, String sourceEncoding) { byte[] bytes = str.getBytes(Charset.forName(sourceEncoding)); return new String(bytes); } // 将默认编码的字符串转换为指定编码的字符串 public static String convertToEncoding(String str, String targetEncoding) { byte[] bytes = str.getBytes(); return new String(bytes, Charset.forName(targetEncoding)); } } ``` 使用示例: ```java public class Main { public static void main(String[] args) { String str1 = "文字符串"; // 将UTF-8编码的字符串转换为默认编码的字符串 String defaultEncodingStr = EncodingUtils.convertToDefaultEncoding(str1, "UTF-8"); System.out.println("Default Encoding: " + defaultEncodingStr); // 将默认编码的字符串转换为GBK编码的字符串 String targetEncodingStr = EncodingUtils.convertToEncoding(defaultEncodingStr, "GBK"); System.out.println("Target Encoding: " + targetEncodingStr); } } ``` 在上述示例工具类`EncodingUtils`提供了两个静态方法。`convertToDefaultEncoding()`方法将指定编码的字符串转换为默认编码的字符串,而`convertToEncoding()`方法将默认编码的字符串转换为指定编码的字符串。 ### 回答2: Java字符串编码转换工具类是一种用于处理字符串编码转换工具类,它可以将字符串从一种字符编码转换为另一种字符编码。在Java,字符串的编码可以使用标准的UTF-8、UTF-16、ISO-8859-1等编码方式。 这个工具类通常提供以下几种方法: 1. `toUTF8(String str)`:将字符串从其他编码转换为UTF-8编码。 2. `fromUTF8(String str)`:将UTF-8编码的字符串转换为其他编码。 3. `toISO88591(String str)`:将字符串从其他编码转换为ISO-8859-1编码。 4. `fromISO88591(String str)`:将ISO-8859-1编码的字符串转换为其他编码。 使用这个工具类可以避免在转换编码时出现乱码或者字符串不可识别的问题。例如,当我们从外部资源读取数据时,如果字符串的编码与程序默认字符编码不一致,就会导致乱码,这时可以使用这个工具类进行编码转换。 在实现这个工具类时,可以使用Java提供的相关类库,如`java.nio.charset.Charset`、`java.nio.CharBuffer`等类来进行编码转换操作。首先,通过指定源编码和目标编码,创建`Charset`对象;然后,使用`encode`方法将源字符串编码成字节序列,并使用目标`Charset`对象的`decode`方法将字节序列解码成目标编码的字符串。 使用这个工具类时,需要注意的是源编码和目标编码必须是支持的字符编码,否则会抛出编码不支持的异常。此外,还应该注意对输入的异常情况进行处理,例如空字符串或空指针异常,以确保程序的健壮性。 总之,Java字符串编码转换工具类是一个方便实用的工具,可以帮助我们在不同编码间进行转换,避免乱码的问题,提高程序的稳定性和可靠性。 ### 回答3: Java提供了许多内置的工具类来方便字符串编码转换。其最常用的工具类是`java.nio.charset.Charset`和`java.lang.String`类。 首先,`Charset`类包含了许多常见的字符集,比如UTF-8、GBK、ISO-8859-1等。我们可以使用`Charset.forName(String charsetName)`方法来获取指定字符集的一个实例。 接下来,`String`类提供了几个方法来进行字符串编码转换。其最常用的是`getBytes(String charsetName)`方法,它将字符串按照指定的字符集转换为字节数组。例如,如果我们想将字符串转换为UTF-8编码的字节数组,可以使用`getBytes("UTF-8")`方法。 除了将字符串转换为字节数组,`String`类还提供了`getBytes()`方法,它将字符串按照默认的字符集转换为字节数组。默认的字符集可以通过调用`Charset.defaultCharset()`方法获取。 另外,如果我们想将字节数组转换为字符串,可以使用`String`类的构造方法`String(byte[] bytes, Charset charset)`。该构造方法将字节数组按照指定的字符集转换为字符串。 除了上述的方法,还有一些其他的工具类可以辅助字符串编码转换。比如,`java.io.InputStreamReader`和`java.io.OutputStreamWriter`类提供了将字节流与字符流进行转换的功能。 总结来说,Java提供了丰富的工具类来进行字符串编码转换。我们可以通过`Charset`类获取指定字符集的实例,通过`String`类的相关方法来进行字符串与字节数组之间的转换。另外,还可以使用`java.io.InputStreamReader`和`java.io.OutputStreamWriter`类进行字节流与字符流之间的转换。这些工具类的使用可以方便地实现字符串编码转换的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值