Mapstruct映射时能否避免为Map指定默认初始化大小?
Mapstruct 避免Map实例化时指定初始大小的解决方法
针对你遇到的Mapstruct 1.5.3.Final版本中,Map映射生成代码因指定初始大小导致Pdx序列化异常的问题,可通过以下几种方式解决:
方法一:自定义Map映射方法(适用于1.5.x版本)
在你的CarMapper接口中手动定义Map转换逻辑,跳过初始容量计算:
import org.mapstruct.Named; import java.util.LinkedHashMap; import java.util.Map; @Named("mapWithoutInitialSize") default Map<String, ObjectTwo> mapWithoutInitialSize(Map<String, ObjectTwo> source) { if (source == null) { return null; } // 直接创建无初始大小指定的LinkedHashMap Map<String, ObjectTwo> target = new LinkedHashMap<>(); target.putAll(source); return target; }
然后在对应的对象映射方法中指定使用该自定义方法:
@Mapping(target = "myMap", qualifiedByName = "mapWithoutInitialSize") CarDto carToCarDto(Car car);
如果是全局的Map<String, ObjectTwo>类型转换,@Named注解会让Mapstruct自动优先使用这个自定义方法,无需每个@Mapping都指定。
方法二:升级至Mapstruct 1.6+版本并配置阈值
从Mapstruct 1.6版本开始,新增了控制Map初始容量的配置项mapstruct.map.initial-capacity-threshold:
- 当原Map的size小于等于该阈值时,生成代码会使用Map的默认初始容量(如LinkedHashMap默认的16),而非计算出的动态值
- 设置一个足够大的阈值(比如999999),即可让所有Map都使用默认初始容量
Maven配置示例:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>11</source> <target>11</target> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.6.0.Final</version> </path> </annotationProcessorPaths> <compilerArgs> <compilerArg>-Amapstruct.map.initial-capacity-threshold=999999</compilerArg> </compilerArgs> </configuration> </plugin> </plugins> </build>
Gradle配置示例:
compileJava { options.compilerArgs += [ '-Amapstruct.map.initial-capacity-threshold=999999' ] }
方法三:使用@MapMapping指定初始容量(1.6+版本支持)
在单独的Map映射方法上添加@MapMapping注解,直接指定初始容量为默认值:
import org.mapstruct.MapMapping; @MapMapping(initialCapacity = 16) Map<String, ObjectTwo> stringObjectTwoToStringObjectTwo(Map<String, ObjectTwo> source);
这样生成的代码会直接用new LinkedHashMap<>(16)创建Map,避免动态计算的初始大小。
补充说明:你看到的两种不同生成逻辑,是因为Mapstruct在处理Map时:
- 如果键值类型无需转换(源和目标类型一致),会直接调用
new LinkedHashMap<>(source)复制原Map - 如果键或值需要类型转换,则会计算初始容量创建新Map,再逐个转换元素放入
内容的提问来源于stack exchange,提问作者AntoCode
相关产品推荐
相关产品推荐

