Java JSON解析花费太多时间-Android

Java JSON解析花费太多时间-Android,java,android,json,parsing,Java,Android,Json,Parsing,我有一个JSON文件airports.JSON,其中包含5720个对象,我想用Java将该文件解析为Airport对象。 下面的代码是我如何解析它的,问题是,完全解析所有文件需要花费太多的时间,大约1分50秒 ArrayList<Airport> arrayAirports = new ArrayList<>(); String json_response = loadJSONFromAsset(); try { JSONObjec

我有一个JSON文件
airports.JSON
,其中包含5720个对象,我想用Java将该文件解析为Airport对象。 下面的代码是我如何解析它的,问题是,完全解析所有文件需要花费太多的时间,大约1分50秒

    ArrayList<Airport> arrayAirports = new ArrayList<>();
    String json_response = loadJSONFromAsset();
    try {
        JSONObject airports = new JSONObject(json_response.trim());

        Log.d("Length Array 0", String.valueOf(airports.names().length()));
        Log.d("Length Array 1", String.valueOf(arrayAirports.size()));
        for(int i = 0; i<airports.names().length(); i++){
                JSONObject jsonAirport = airports.getJSONObject(airports.names().getString(i));
                Airport newAirport = new Airport();
                newAirport.name = jsonAirport.getString("name");
                newAirport.city = jsonAirport.getString("city");
                newAirport.country = jsonAirport.getString("country");
                newAirport.latitude = jsonAirport.getString("latitude");
                newAirport.longitude = jsonAirport.getString("longitude");
                newAirport.altitude = jsonAirport.getString("altitude");
                newAirport.iata = jsonAirport.getString("iata");
                newAirport.icao = jsonAirport.getString("icao");
                newAirport.timeZone = jsonAirport.getString("timezone");
                newAirport.dst = jsonAirport.getString("dst");
                arrayAirports.add(newAirport);
        }



    } catch (JSONException e1) {
        e1.printStackTrace();
    }

    Log.d("Length Array 2", String.valueOf(arrayAirports.size()));
ArrayList

改用它测量速度。虽然仅仅读取文件可能需要很长时间,但整整一分钟似乎很糟糕

由于您提到您不知道如何使用GSON。不过,它假设您是从网络调用中获取文件,因此您需要应用它来使用本地JSON文件。

您将一个(我想?)大的JSON数据文件直接放入JSONObject中

在这种情况下,建议使用基于令牌的读取器,例如

直接从文档粘贴:

public List readJsonStream(InputStream in ) throws IOException {
    JsonReader reader = new JsonReader(new InputStreamReader( in , "UTF-8"));
    try {
        return readMessagesArray(reader);
        finally {
            reader.close();
        }
    }

    public List readMessagesArray(JsonReader reader) throws IOException {
        List messages = new ArrayList();

        reader.beginArray();
        while (reader.hasNext()) {
            messages.add(readMessage(reader));
        }
        reader.endArray();
        return messages;
    }

    public Message readMessage(JsonReader reader) throws IOException {
        long id = -1;
        String text = null;
        User user = null;
        List geo = null;

        reader.beginObject();
        while (reader.hasNext()) {
            String name = reader.nextName();
            if (name.equals("id")) {
                id = reader.nextLong();
            } else if (name.equals("text")) {
                text = reader.nextString();
            } else if (name.equals("geo") && reader.peek() != JsonToken.NULL) {
                geo = readDoublesArray(reader);
            } else if (name.equals("user")) {
                user = readUser(reader);
            } else {
                reader.skipValue();
            }
        }
        reader.endObject();
        return new Message(id, text, user, geo);
    }

    public List readDoublesArray(JsonReader reader) throws IOException {
        List doubles = new ArrayList();

        reader.beginArray();
        while (reader.hasNext()) {
            doubles.add(reader.nextDouble());
        }
        reader.endArray();
        return doubles;
    }

    public User readUser(JsonReader reader) throws IOException {
        String username = null;
        int followersCount = -1;

        reader.beginObject();
        while (reader.hasNext()) {
            String name = reader.nextName();
            if (name.equals("name")) {
                username = reader.nextString();
            } else if (name.equals("followers_count")) {
                followersCount = reader.nextInt();
            } else {
                reader.skipValue();
            }
        }
        reader.endObject();
        return new User(username, followersCount);
    }
}

不知道这是否影响性能,但您不应该重复调用
names()
。在循环之前分配给变量,然后使用它

JSONArray names = airports.names();
Log.d("Length Array 0", String.valueOf(names.length()));
Log.d("Length Array 1", String.valueOf(arrayAirports.size()));
for(int i = 0; i<names.length(); i++){
    JSONObject jsonAirport = airports.getJSONObject(names.getString(i));
    // code
}

请尝试使用第三方库,而不是手动执行。我现在正在尝试使用它,但我不知道如何循环遍历JSON文件,并在每次迭代中添加Airport对象jsonObject.names()。。。两次?这是我唯一能想到的方法我不知道这对性能是否重要<代码>公共JSONArray名称(){JSONArray ja=new JSONArray();迭代器键=this.keys();而(keys.hasNext()){ja.put(keys.next();}返回ja.length()==0?null:ja;}
@Selvin更糟糕的是,如果对象为空,它返回
null
,因此,这是一种非常危险的方法,因为它可能会导致
NullPointerException
。感谢您在不改变我太多工作的情况下为我完成了这项工作code@IlhemNemri请注意,由于存在NPE危险,您应该使用
键()
,而不是
名称()
,这对性能也有好处,因为它不必先将名称复制到数组中。
Log.d("Length Array 0", String.valueOf(airports.length()));
Log.d("Length Array 1", String.valueOf(arrayAirports.size()));
for (Iterator<String> nameIter = airports.keys(); nameIter.hasNext(); ){
    String name = nameIter.next();
    JSONObject jsonAirport = airports.getJSONObject(name);
    // code
}