Open allenwoody opened 4 months ago
包含TreeSet属性的对象,在序列化反序列化时TreeSet内值乱序
如何操作可以重现该问题:
main
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.annotation.JSONField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; import java.util.Arrays; import java.util.Set; import java.util.TreeSet; import static com.alibaba.fastjson2.JSONReader.Feature.UseDefaultConstructorAsPossible; @Data public class TrainingDataParamsSet { @ApiModelProperty(value = "算法") private Set<String> algorithms; /** * 平滑系数,lambda */ @ApiModelProperty(value = "平滑系数,lambda") private Set<BigDecimal> algorithmParameters; /** * 阈值 */ @ApiModelProperty(value = "阈值") private Set<BigDecimal> thresholds; /** * 截断方式,1.去除-remove, 2-替换-replace */ @ApiModelProperty(value = "截断方式,1.去除-remove, 2-替换-replace") private Set<Integer> truncationMethods; /** * 截断率 */ @ApiModelProperty(value = "截断率") private Set<BigDecimal> truncationRates; /** * 步长 */ @ApiModelProperty(value = "步长") private Set<Integer> steps; /** * 误差引入方式 */ @ApiModelProperty(value = "误差引入方式") private Set<String> errorIntroductionMethods; /** * 系统误差-恒定误差 */ @ApiModelProperty(value = "系统误差-恒定误差") private Set<BigDecimal> systematicErrors; /** * 系统误差-比例误差 */ @ApiModelProperty(value = "系统误差-比例误差") private Set<BigDecimal> proportionalErrors; /** * 高斯分布标准差 */ @ApiModelProperty(value = "高斯分布标准差") private Set<BigDecimal> gaussianStds; /** * 高斯分布均值 */ @ApiModelProperty(value = "高斯分布均值") private Set<BigDecimal> gaussianMeans; /** * U型分布标准差 */ @JSONField(name = "uShapedStds") @ApiModelProperty(value = "U型分布标准差") private Set<BigDecimal> uShapedStds; /** * U型分布均值 */ @JSONField(name = "uShapedMeans") @ApiModelProperty(value = "U型分布均值") private Set<BigDecimal> uShapedMeans; /** * 均匀分布标准差 */ @ApiModelProperty(value = "均匀分布标准差") private Set<BigDecimal> uniformStds; /** * FPR1,falsePositiveRate,假阳率 */ @ApiModelProperty(value = "FPR1,falsePositiveRate,假阳率") private ValueRange fpr1s; /** * TPR1,truePositiveRate,真阳率 */ @ApiModelProperty(value = "TPR1,truePositiveRate,真阳率") private ValueRange tpr1s; /** * ANped(Adult Neutrophil per Erythroid cell division)骨髓中成人中性粒细胞与红细胞生成细胞之间的比率 */ @JSONField(name = "aNped") @ApiModelProperty(value = "ANped(Adult Neutrophil per Erythroid cell division)骨髓中成人中性粒细胞与红细胞生成细胞之间的比率") private ValueRange aNpeds; /** * MNped(Mature Neutrophil per Erythroid cell division)骨髓中成熟中性粒细胞与红细胞生成细胞之间的比率 */ @JSONField(name = "mNped") @ApiModelProperty(value = "MNped(Mature Neutrophil per Erythroid cell division)骨髓中成熟中性粒细胞与红细胞生成细胞之间的比率") private ValueRange mNpeds; /** * Nped95,95% 阴性预测值(95% NPV, NPed95) */ @ApiModelProperty(value = "Nped95,95% 阴性预测值(95% NPV, NPed95)") private ValueRange nped95s; /** * 不稳定指标 */ @ApiModelProperty(value = "不稳定指标") private ValueRange instabilityIndices; // 构造方法 public TrainingDataParamsSet() { // 初始化所有 Set 类型属性为 TreeSet this.algorithms = new TreeSet<>(); this.algorithmParameters = new TreeSet<>(); this.thresholds = new TreeSet<>(); this.truncationMethods = new TreeSet<>(); this.truncationRates = new TreeSet<>(); this.steps = new TreeSet<>(); this.errorIntroductionMethods = new TreeSet<>(); this.systematicErrors = new TreeSet<>(); this.proportionalErrors = new TreeSet<>(); this.gaussianStds = new TreeSet<>(); this.gaussianMeans = new TreeSet<>(); this.uShapedStds = new TreeSet<>(); this.uShapedMeans = new TreeSet<>(); this.uniformStds = new TreeSet<>(); this.fpr1s = new ValueRange(); this.tpr1s = new ValueRange(); this.aNpeds = new ValueRange(); this.mNpeds = new ValueRange(); this.nped95s = new ValueRange(); this.instabilityIndices = new ValueRange(); } public static void main(String[] args) { // 实例化 TrainingDataParamsSet 对象并设置属性值 TrainingDataParamsSet trainingDataParamsSet = new TrainingDataParamsSet(); // 设置属性值 trainingDataParamsSet.setSteps(new TreeSet<>(Arrays.asList(10, 30, 50, 70, 100, 130, 150, 200))); trainingDataParamsSet.setAlgorithms(new TreeSet<>(Arrays.asList("ewma", "ma"))); trainingDataParamsSet.setUShapedStds(new TreeSet<>(Arrays.asList(new BigDecimal("0.33"), new BigDecimal("0.5"), new BigDecimal("1.5"), new BigDecimal("3.0")))); trainingDataParamsSet.setUShapedMeans(new TreeSet<>(Arrays.asList(new BigDecimal("-0.5"), new BigDecimal("-0.3"), BigDecimal.ZERO, new BigDecimal("0.3"), new BigDecimal("0.5")))); trainingDataParamsSet.setTruncationRates(new TreeSet<>(Arrays.asList(new BigDecimal("0.01"), new BigDecimal("0.02"), new BigDecimal("0.03"), new BigDecimal("0.04"), new BigDecimal("0.05"), new BigDecimal("0.1"), new BigDecimal("0.2")))); trainingDataParamsSet.setTruncationMethods(new TreeSet<>(Arrays.asList(1, 2))); trainingDataParamsSet.setErrorIntroductionMethods(new TreeSet<>(Arrays.asList("even", "gauss", "ratio", "stable", "u"))); String json = JSON.toJSONString(trainingDataParamsSet); System.out.println(json); TrainingDataParamsSet t = JSON.parseObject(json, TrainingDataParamsSet.class); System.out.println("----"); System.out.println(t); } }
通过JSON.parseObject(json, TrainingDataParamsSet.class);得到的对象,里面的TreeSet实例是有序的
TrainingDataParamsSet(algorithms=[ma, ewma], algorithmParameters=[], thresholds=[], truncationMethods=[1, 2], truncationRates=[0.02, 0.1, 0.01, 0.05, 0.04, 0.03, 0.2], steps=[50, 130, 100, 70, 150, 200, 10, 30], errorIntroductionMethods=[gauss, even, u, stable, ratio], systematicErrors=[], proportionalErrors=[], gaussianStds=[], gaussianMeans=[], uShapedStds=[0.33, 1.5, 3.0, 0.5], uShapedMeans=[0, -0.5, -0.3, 0.5, 0.3], uniformStds=[], fpr1s=ValueRange(max=null, min=null), tpr1s=ValueRange(max=null, min=null), aNpeds=ValueRange(max=null, min=null), mNpeds=ValueRange(max=null, min=null), nped95s=ValueRange(max=null, min=null), instabilityIndices=ValueRange(max=null, min=null))
看了下源码,应该是我用Set声明变量的锅,反序列化时直接变成HashSet了 改用TreeSet声明就没问题。还是想问问,用Set声明就不行吗
问题描述
包含TreeSet属性的对象,在序列化反序列化时TreeSet内值乱序
环境信息
重现步骤
如何操作可以重现该问题:
main
方法期待的正确结果
通过JSON.parseObject(json, TrainingDataParamsSet.class);得到的对象,里面的TreeSet实例是有序的
相关日志输出
{"aNped":{},"algorithmParameters":[],"algorithms":["ewma","ma"],"errorIntroductionMethods":["even","gauss","ratio","stable","u"],"fpr1s":{},"gaussianMeans":[],"gaussianStds":[],"instabilityIndices":{},"mNped":{},"nped95s":{},"proportionalErrors":[],"steps":[10,30,50,70,100,130,150,200],"systematicErrors":[],"thresholds":[],"tpr1s":{},"truncationMethods":[1,2],"truncationRates":[0.01,0.02,0.03,0.04,0.05,0.1,0.2],"uShapedMeans":[-0.5,-0.3,0,0.3,0.5],"uShapedStds":[0.33,0.5,1.5,3.0],"uniformStds":[]}
TrainingDataParamsSet(algorithms=[ma, ewma], algorithmParameters=[], thresholds=[], truncationMethods=[1, 2], truncationRates=[0.02, 0.1, 0.01, 0.05, 0.04, 0.03, 0.2], steps=[50, 130, 100, 70, 150, 200, 10, 30], errorIntroductionMethods=[gauss, even, u, stable, ratio], systematicErrors=[], proportionalErrors=[], gaussianStds=[], gaussianMeans=[], uShapedStds=[0.33, 1.5, 3.0, 0.5], uShapedMeans=[0, -0.5, -0.3, 0.5, 0.3], uniformStds=[], fpr1s=ValueRange(max=null, min=null), tpr1s=ValueRange(max=null, min=null), aNpeds=ValueRange(max=null, min=null), mNpeds=ValueRange(max=null, min=null), nped95s=ValueRange(max=null, min=null), instabilityIndices=ValueRange(max=null, min=null))
附加信息