Java中如何将Candlestick对象集合转换为指定嵌套结构JSON并正确序列化对象属性
解决Candlestick对象JSON序列化及分组问题
首先,你的问题有两个核心点需要解决:Map分组逻辑错误导致每次循环覆盖之前的数据,以及Candlestick类缺少必要的访问配置导致JSON序列化时输出对象引用而非属性值。
1. 修复Map的分组逻辑
你当前的代码每次循环都会用Map.of()创建全新的嵌套Map,并且直接把整个simCandlestickList赋值给对应的Period,这会覆盖之前的所有分组数据,而且每个Period下都会包含所有蜡烛图数据,而不是对应分组的单个对象。正确的做法是逐层检查各级Map/List是否存在,不存在则创建,然后将当前Candlestick添加到对应的列表中:
Map<String, Map<String, Map<String, List<Candlestick>>>> candles = new HashMap<>(); for (Candlestick candlestick : simCandlestickList) { // 1. 获取或创建Market对应的Map Map<String, Map<String, List<Candlestick>>> marketMap = candles.computeIfAbsent( candlestick.getMarket(), k -> new HashMap<>() ); // 2. 获取或创建Coin对应的Map Map<String, List<Candlestick>> coinMap = marketMap.computeIfAbsent( candlestick.getCoin(), k -> new HashMap<>() ); // 3. 获取或创建Period对应的List List<Candlestick> periodList = coinMap.computeIfAbsent( candlestick.getPeriod(), k -> new ArrayList<>() ); // 4. 将当前蜡烛图对象添加到对应列表 periodList.add(candlestick); }
computeIfAbsent方法会自动帮我们处理"不存在则创建"的逻辑,避免了繁琐的null检查。
2. 修复JSON序列化问题
你看到的com.company.Candlestick@xxxx是Java对象默认的toString()输出,这是因为序列化库(比如Jackson、Gson)无法访问Candlestick类的私有属性。解决这个问题有两种常见方式:
方式一:添加所有属性的Getter方法
序列化库通常会通过Getter方法读取对象属性,所以给Candlestick类补充所有需要序列化的属性的Getter:
public class Candlestick { private long MainKey; private String Market; private String Coin; private String Period; private double Open; private double High; private double Low; private double Close; // 已有的Getter public String getMarket() { return Market; } public String getCoin() { return Coin; } public String getPeriod() { return Period; } // 新增需要序列化的属性的Getter public long getMainKey() { return MainKey; } public double getOpen() { return Open; } public double getHigh() { return High; } public double getLow() { return Low; } public double getClose() { return Close; } }
方式二:使用序列化注解直接访问字段
如果不想添加Getter,可以用Jackson的@JsonProperty注解标记私有字段,让序列化库直接读取字段值:
import com.fasterxml.jackson.annotation.JsonProperty; public class Candlestick { @JsonProperty private long MainKey; @JsonProperty private String Market; @JsonProperty private String Coin; @JsonProperty private String Period; @JsonProperty private double Open; @JsonProperty private double High; @JsonProperty private double Low; @JsonProperty private double Close; // 保留已有的Getter(如果需要在其他地方使用) public String getMarket() { return Market; } public String getCoin() { return Coin; } public String getPeriod() { return Period; } }
3. 序列化Map为JSON
完成上述两步后,用序列化库将Map转为JSON即可。比如用Jackson的示例:
import com.fasterxml.jackson.databind.ObjectMapper; ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(candles); System.out.println(json);
或者用Gson:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; Gson gson = new GsonBuilder().setPrettyPrinting().create(); String json = gson.toJson(candles); System.out.println(json);
这样就能得到你期望的JSON结构,每个Candlestick对象都会输出对应的属性值。
内容的提问来源于stack exchange,提问作者A. Vreeswijk
相关产品推荐
相关产品推荐

