Java: объединение двух объектов json вместе с первичным ключом

Допустим, у меня есть два массива JSONObjects в памяти, и у каждого объекта есть ключ, похожий в обоих массивах:

Массив 1

[
  {
    "name": "Big Melons Co.",
    "location": "Inner City Dubai"
    "id": "1A"
  },
  {
    "name": "Pear Flavored Juices Ltd",
    "location": "Seychelles"
    "id": "2A"
  },
  {
    "name": "Squeeze My Lemons LLC",
    "location": "UK"
    "id": "3A"
  }, {other JSON Objects...} ]

Массив 2

[
  {
    "acceptsCard": "true"
    "id": "1A"
  },
  {
    "acceptsCard": "false"
    "id": "2A"
  },
  {
    "acceptsCard": "false"
    "id": "3A"
  }, {other JSON Objects...} ]

Теперь я хочу объединить два массива вместе на основе первичного ключа «id», чтобы они стали одним на стороне моего сервера, а затем отправить результаты обратно в мой интерфейс — результирующий список объектов должен выглядеть так:

ОБЪЕДИНЕННЫЙ МАССИВ (Результат)

  [
      {
        "name": "Great Juice Co.",
        "location": "Inner City Dubai"
        "acceptsCard": "true"
        "id": "1A"
      },
      {
        "name": "Pear Flavored Juices Ltd",
        "location": "Seychelles"
        "acceptsCard": "false"
        "id": "2A"
      },
      {
        "name": "Squeeze My Lemons LLC",
        "location": "UK"
        "acceptsCard": "false"
        "id": "3A"
      }, {other JSON Objects...} ]

Как я могу сделать это эффективно?

Я могу придумать один очень неэффективный способ сделать это (я боюсь реализовать это) - я бы прокручивал каждый элемент в массиве 1 или 2 и использовал метод equal() для строки в поле «id», чтобы увидеть совпадают ли эти два. Если они совпадают, я бы создал новый JSONObject, содержащий оба поля из массива 1 и 2.


person Simon    schedule 29.09.2015    source источник
comment
Java или JavaScript? (спрашивая «потому что Java ‹› JavaScript)   -  person blurfus    schedule 29.09.2015
comment
Джава. Это в шапке вопроса.   -  person Simon    schedule 29.09.2015
comment
О, я знаю, но первый ответ (не вижу его сейчас) сбил меня с толку, потому что он предоставлял код JS, поэтому я хотел убедиться   -  person blurfus    schedule 29.09.2015
comment
Я не думаю, что парень прочитал вопрос или увидел теги к вопросу - я вижу, он удалил его сейчас.   -  person Simon    schedule 29.09.2015
comment
Есть ли вероятность того, что ключи первого массива могут быть найдены во втором массиве? (кроме "id", конечно)   -  person blurfus    schedule 29.09.2015
comment
Вы имеете в виду, что acceptsCard будет найден в обоих массивах? Неа. Массивы получены с двух разных серверов, и каждый из них дает свои уникальные свойства json - единственное, что кажется одинаковым, - это идентификатор   -  person Simon    schedule 29.09.2015
comment
Затем попробуйте: stackoverflow.com/questions/19566081/ или stackoverflow .com/questions/2403132/concat-multiple-jsonobjects   -  person blurfus    schedule 29.09.2015


Ответы (1)


Моя Java немного ржавая, но я бы использовал карту.

List<JSONObject> objectsA = ... ;
List<JSONObject> objectsB = ... ;

Map entries = new HashMap<String, JSONObject>();
List<JSONObject> allObjects = new ArrayList<JSONObject>();
allObjects.addAll(objectsA);
allObjects.addAll(objectsB);

for (JSONObject obj: allObjects) {
    String key = obj.getString("id");
    JSONObject existing = entries.get(key);
    if (existing == null) {
        existing = new JSONObject();
        entries.put(key, existing);
    }

    for (String subKey : obj.keys()) {
        existing.put(subKey, obj.get(subKey));
    }
}

List<JSONObject> merged = entries.values();

Это более эффективно, чем два вложенных цикла, и еще есть возможности для улучшения.

РЕДАКТИРОВАТЬ: ссылки на внешнюю документацию и соответствующие ответы.

person ctrlc-root    schedule 29.09.2015
comment
Не уверен, что понимаю код здесь - может быть, вы можете уточнить. Вы создаете цикл for для ключей в объекте, но в идентификаторе вызова объекта есть только 1 ключ, поэтому вы не можете зацикливаться на этом. Также hashmap не имеет установленного метода... - person Simon; 29.09.2015
comment
@Simon упс, это была синтаксическая ошибка, и я просто исправил ее и добавил строку, чтобы проиллюстрировать удаление объединенных объектов с карты. код в основном перебирает все объекты из обоих списков и объединяет их свойства в один JSONObject existing на основе ключа id. этот объект хранится в Map, поэтому его извлечение с помощью id выполняется быстро. Имеет ли это смысл? - person ctrlc-root; 29.09.2015
comment
@Simon, что касается цикла for, не имеет значения, имеет ли объект 0 или более ключей, функция JSONObject.keys() вернет Iterator по их списку (этот список может оказаться пустым или содержать только один элемент). Как я уже сказал, я давно не программировал на Java, и вам может понадобиться изменить этот цикл, чтобы явно работать с возвращаемым объектом Iterator, но не уверен, что вы можете использовать там for each. - person ctrlc-root; 29.09.2015
comment
Мне нужно немного подумать об этом, но то, что вы там сделали, имеет большой смысл. Сначала мне нужно будет проверить это, и я свяжусь с вами. - person Simon; 29.09.2015
comment
Спасибо - это работает, но я понял, что мне, возможно, придется сделать шаг назад и вместо этого объединить на уровне pojo. Я опубликую новый вопрос в ближайшее время. - person Simon; 30.09.2015