如何使用 GSON 反序列化 Array 内的 Double 数组?

Posted

技术标签:

【中文标题】如何使用 GSON 反序列化 Array 内的 Double 数组?【英文标题】:How can I de-serialize Array of Double inside of Array using GSON? 【发布时间】:2021-12-15 09:38:55 【问题描述】:

我有一个 JSON 文件:


  "prices": [
    [
      1635631832100,
      61607.43864571635
    ],
    [
      1635632085704,
      61575.780699431976
    ]
  ],
  "market_caps": [
    [
      1635631398809,
      1164158508809.9917
    ],
    [
      1635631832100,
      1164158508809.9917
    ],
    [
      1635632085704,
      1164158508809.9917
    ]
  ],
  "total_volumes": [
    [
      1635632420811,
      30767786519.758457
    ],
    [
      1635632594220,
      30875566056.458145
    ],
    [
      1635632959263,
      30967148014.50128
    ],
    [
      1635633219013,
      30718683632.270718
    ]
  ]

我的对象类是这样的:

public class HistoricalPrices 
    
    private List<List<Double>> prices;
    private List<List<Double>> market_caps;
    private List<List<Double>> total_volumes;

    public List<List<Double>> getPrices() 
        return prices;
    

    public List<List<Double>> getMarket_caps() 
        return market_caps;
    

    public List<List<Double>> getTotal_volumes() 
        return total_volumes;
    

我不确定我在这里做错了什么,因为当我尝试反序列化 JSON 文件时,我的数组字段为空。 Double 值的“无名”数组让我失望,但似乎我的对象类应该在这里工作。该文件来自使用 GSON 工厂的改造调用。

编辑:

改造界面:

@GET("coins/id/market_chart/range")
Call<HistoricalPrices> getHistoricalPrices(
        @Path("id") String id, @Query("vs_currency")String currency, @Query("from") double startDate, @Query("to") double endDate);

改装电话:

private void populateHistoricalPrices() 
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://api.coingecko.com/api/v3/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    CoinGeckoApi coinGeckoApi = retrofit.create(CoinGeckoApi.class);
    Call<HistoricalPrices> call = coinGeckoApi.getHistoricalPrices("bitcoin", "usd", 1635597419, 1635633419);

    call.enqueue(new Callback<HistoricalPrices>() 
        @Override
        public void onResponse(Call<HistoricalPrices> call, Response<HistoricalPrices> response) 

            if(!response.isSuccessful())
                //need to display response error
                return;
            

            TextView textView = ((Activity) context).findViewById(R.id.mainTextView);
            textView.append(response.body().toString());
            HistoricalPrices historicalPrices = response.body();

        

        @Override
        public void onFailure(Call<HistoricalPrices> call, Throwable t) 

        
    );

    

【问题讨论】:

我猜 GSON 会因为数组中的第一个是 Long 而第二个是 double 而感到困惑。尝试创建一个 POJO,你会看到。 我只是假设 GSON 会将 long 转换为 double。我以前做过这样的事情,我有一个 long 和 double 并且 GSON 反序列化它就好了。 【参考方案1】:

你必须在这里使用 String 而不是 Long

public class HistoricalPrices 

    @SerializedName("prices")
    private List<List<String>> prices = null;
    @SerializedName("market_caps")
    private List<List<String>> marketCaps = null;
    @SerializedName("total_volumes")
    private List<List<String>> totalVolumes = null;

    public List<List<String>> getPrices() 
        return prices;
    

    public void setPrices(List<List<String>> prices) 
        this.prices = prices;
    

    public List<List<String>> getMarketCaps() 
        return marketCaps;
    

    public void setMarketCaps(List<List<String>> marketCaps) 
        this.marketCaps = marketCaps;
    

    public List<List<String>> getTotalVolumes() 
        return totalVolumes;
    

    public void setTotalVolumes(List<List<String>> totalVolumes) 
        this.totalVolumes = totalVolumes;
    

    @Override
    public String toString() 
        return "HistoricalPrices" + "prices=" + prices + ", marketCaps=" + marketCaps + ", totalVolumes=" + totalVolumes + '';
    

您在查询中使用双精度而不是字符串作为时间戳(unix) 在这里所以请使用这样的字符串

    @GET("coins/id/market_chart/range")
Call<HistoricalPrices> getHistoricalPrices(
        @Path("id") String id, @Query("vs_currency")String currency, @Query("from") String startDate, @Query("to") String endDate);

    Call<HistoricalPrices> call = coinGeckoApi.getHistoricalPrices("bitcoin", "USD", "1635597419", "1635633419");

请查看此截图

【讨论】:

对我不起作用,仍然无法反序列化。 你能分享一下你在哪里做这个反序列化的代码吗? 好的,我添加了一个编辑,显示使用 GsonConverterFactory 进行改造调用。 你遇到了什么错误? 我没有收到错误,只有空数组字段。

以上是关于如何使用 GSON 反序列化 Array 内的 Double 数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Gson 反序列化 XMLGregorianCalender?

完全理解Gson:Gson反序列化

使用 gson 反序列化反序列化对象的内部对象

如何使用Gson反序列化Kotlin数组列表?

如何使用 GSON 或 Java 中的其他 JSON 库反序列化列表?

使用 Gson 序列化和反序列化枚举 [重复]