【问题标题】:Parsing unnamed nested arrays with minimal-json?使用最小 json 解析未命名的嵌套数组?
【发布时间】:2017-09-21 23:00:05
【问题描述】:

所以我正在开发一个相当简单的 Java 程序,它从加密货币交易所获取市场数据并向用户显示信息。我正在使用最小 json 库。

这是我当前的代码:

public class Market {
    static JsonArray arrayBittrex;

    public static void startTimer(){
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                String url = "https://bittrex.com/api/v1.1/public/getmarketsummaries";
                try {
                    URL url2 = new URL(url);
                    URLConnection con = url2.openConnection();
                    InputStream in = con.getInputStream();
                    String encoding = "UTF-8";
                    String body = IOUtils.toString(in, encoding);
                    arrayBittrex = Json.parse(body).asObject().get("result").asArray();
                }
                catch(MalformedURLException e) {}
                catch(IOException e) {}
            }
        }, 0,5000);
    }

    public static float getPrice(String exchange, String market) {
        for (JsonValue item : arrayBittrex) {
            float last = item.asObject().getFloat("Last", 0);
            System.out.println(last);
            return last;
        }
        return 0;
    }
}

此代码适用于简单的 json,例如(来自https://bittrex.com/api/v1.1/public/getmarketsummary?market=btc-ltc):

{
    "success" : true,
    "message" : "",
    "result" : [{
            "MarketName" : "BTC-LTC",
            "High" : 0.01350000,
            "Low" : 0.01200000,
            "Volume" : 3833.97619253,
            "Last" : 0.01349998
        }
    ]
}

它将正确返回数组中的“Last”值。 但是,当 json 有多个数组时(如在https://bittrex.com/api/v1.1/public/getmarketsummaries 中),这将不起作用:

{
    "success" : true,
    "message" : "",
    "result" : [{
            "MarketName" : "BTC-888",
            "High" : 0.00000919,
            "Low" : 0.00000820,
            "Volume" : 74339.61396015,
            "Last" : 0.00000820
        }, {
            "MarketName" : "BTC-A3C",
            "High" : 0.00000072,
            "Low" : 0.00000001,
            "Volume" : 166340678.42280999,
            "Last" : 0.00000005
        }
    ]
}

所以我的问题是:如何通过“MarketName”值搜索数组来获得“Last”值?

【问题讨论】:

  • 在您的 getPrice 方法中添加一个 if 检查以检查比较市场的价值

标签: java arrays json parsing minimal-json


【解决方案1】:

这是使用 Java 8 库 Dynamics 解决此问题的直接且安全的方法。我们将把 json 解析成 Map,动态读取映射到我们想要的内容。

所以首先我们可以使用Jackson、Gson之类的东西来转换json -> map。

// com.fasterxml.jackson.core:jackson-databind json -> map
Map jsonMap = new ObjectMapper()
    .enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
    .readValue(jsonStringOrInputSourceEtc, Map.class);

我们现在可以获得Dynamic 实例。例如,获取 BTC-A3C - Last 值。

Dynamic json = Dynamic.from(jsonMap);

BigDecimal a3cLast = json.get("result").children()
    .filter(data -> data.get("MarketName").asString().equals("BTC-A3C"))
    .findAny()
    .flatMap(data -> data.get("Last").maybe().convert().intoDecimal())
    .orElse(BigDecimal.ZERO); 
// 5E-8

或者也许将整个批次转换为 MarketName -> Last 值的地图

Map<String, BigDecimal> marketNameLastValue = json.get("result").children()
    // assume fields are always present, otherwise see #maybe() methods
    .collect(toMap(
        data -> data.get("MarketName").asString(),
        data -> data.get("Last").convert().intoDecimal()
    )); 
// {BTC-A3C=5E-8, BTC-888=0.00000820}

查看更多示例https://github.com/alexheretic/dynamics

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多