1. Введение
В этом руководстве мы рассмотрим несколько подходов к повторению JSONObject
, простого представления JSON для Java.
Мы начнем с наивного решения, а затем рассмотрим что-то более надежное.
2. Итерация через JSONObject
Начнем с простого случая повторения JSON пар имя-значение:
{
"name": "Cake",
"cakeId": "0001",
"cakeShape": "Heart"
}
Для этого мы можем просто перебирать ключи, используя метод keys()
:
void handleJSONObject(JSONObject jsonObject) {
jsonObject.keys().forEachRemaining(key -> {
Object value = jsonObject.get(key);
logger.info("Key: {0}\tValue: {1}", key, value);
}
}
И наш вывод будет:
Key: name Value: Cake
Key: cakeId Value: 0001
Key: cakeShape Value: Heart
3. Обход объекта JSON
Но допустим, что у нас более сложная структура:
{
"batters": [
{
"type": "Regular",
"id": "1001"
},
{
"type": "Chocolate",
"id": "1002"
},
{
"type": "BlueBerry",
"id": "1003"
}
],
"name": "Cake",
"cakeId": "0001"
}
Что означает перебор ключей в данном случае?
Давайте посмотрим, что даст нам наш наивный подход с ключами() :
Key: batters Value: [{"type":"Regular","id":"1001"},{"type":"Chocolate","id":"1002"},
{"type":"BlueBerry","id":"1003"}]
Key: name Value: Cake
Key: cakeId Value: 0001
Это, пожалуй, не так полезно. Похоже, что в данном случае нам нужна не итерация, а обход.
Обход через JSONObject
отличается от итерации по набору ключей JSONObject
.
Для этого нам действительно нужно также проверить тип значения. Давайте представим, что мы делаем это в отдельном методе:
void handleValue(Object value) {
if (value instanceof JSONObject) {
handleJSONObject((JSONObject) value);
} else if (value instanceof JSONArray) {
handleJSONArray((JSONArray) value);
} else {
logger.info("Value: {0}", value);
}
}
Тогда наш подход все еще довольно похож:
void handleJSONObject(JSONObject jsonObject) {
jsonObject.keys().forEachRemaining(key -> {
Object value = jsonObject.get(key);
logger.info("Key: {0}", key);
handleValue(value);
});
}
Единственное, нам нужно подумать о том, как обращаться с массивами.
4. Обход через JSONArray
Давайте попробуем сохранить аналогичный подход с использованием итератора. Однако вместо вызова keys()
мы будем вызывать iterator()
:
void handleJSONArray(JSONArray jsonArray) {
jsonArray.iterator().forEachRemaining(element -> {
handleValue(element)
});
}
Теперь это решение ограничивает, потому что мы объединяем обход с действием, которое мы хотим предпринять . Распространенным подходом к разделению этих двух элементов является использование шаблона «Посетитель » .
5. Вывод
В этой статье мы увидели способ перебора JSONObject
для простых пар имя-значение, проблему, связанную со сложными структурами, и технику обхода для ее решения.
Конечно, это был метод обхода в глубину, но мы могли бы сделать обход в ширину аналогичным образом.
Полный код примера доступен на Github .