[BUG]对象包含有序集合,反序列化时乱序
- Dominant language
- Java
- Stars
- 4.4k
- Forks
- 613
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 6
Description
### 问题描述
包含TreeSet属性的对象,在序列化反序列化时TreeSet内值乱序
### 环境信息
- OS信息: [MacOs 13.41 Apple M1 16 GB]
- JDK信息: [Openjdk 1.8.0_401]
- 版本信息:[Fastjson2 2.0.51]
### 重现步骤
*如何操作可以重现该问题:*
1. 执行 `main` 方法
```java
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 algorithms;
/**
* 平滑系数,lambda
*/
@ApiModelProperty(value = "平滑系数,lambda")
private Set algorithmParameters;
/**
* 阈值
*/
@ApiModelProperty(value = "阈值")
private Set thresholds;
/**
* 截断方式,1.去除-remove, 2-替换-replace
*/
@ApiModelProperty(value = "截断方式,1.去除-remove, 2-替换-replace")
private Set truncationMethods;
/**
* 截断率
*/
@ApiModelProperty(value = "截断率")
private Set truncationRates;
/**
* 步长
*/
@ApiModelProperty(value = "步长")
private Set steps;
/**
* 误差引入方式
*/
@ApiModelProperty(value = "误差引入方式")
private Set errorIntroductionMethods;
/**
* 系统误差-恒定误差
*/
@ApiModelProperty(value = "系统误差-恒定误差")
private Set systematicErrors;
/**
* 系统误差-比例误差
*/
@ApiModelProperty(value = "系统误差-比例误差")
private Set proportionalErrors;
/**
* 高斯分布标准差
*/
@ApiModelProperty(value = "高斯分布标准差")
private Set gaussianStds;
/**
* 高斯分布均值
*/
@ApiModelProperty(value = "高斯分布均值")
private Set gaussianMeans;
/**
* U型分布标准差
*/
@JSONField(name = "uShapedStds")
@ApiModelProperty(value = "U型分布标准差")
private Set uShapedStds;
/**
* U型分布均值
*/
@JSONField(name = "uShapedMeans")
@ApiModelProperty(value = "U型分布均值")
private Set uShapedMeans;
/**
* 均匀分布标准差
*/
@ApiModelProperty(value = "均匀分布标准差")
private Set 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实例是有序的
### 相关日志输出
{"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))
#### 附加信息
Contributor guide
Research direction
Start with the provided main method and reproduce the behavior through JSON.parseObject(json, TrainingDataParamsSet.class). Trace how the Set fields are reconstructed during deserialization; done means the resulting TreeSet instances preserve sorted order for the shown values.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100