使用minimal-json解析未命名的嵌套数组?

时间:2017-09-21 23:00:05

标签: java arrays json parsing minimal-json

所以我正在开发一个相当简单的Java程序,它从加密货币交换中获取市场数据并向用户显示信息。我正在使用minimal-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”值?

1 个答案:

答案 0 :(得分:0)

这是一个直接&使用Java 8库Dynamics解决此问题的无效安全方法。我们要将json解析成Map,将该地图动态地读取到我们想要的地方。

首先我们可以使用Jackson,Gson或其他东西来转换json - >地图。

// 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 的地图 - > 最后

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