Каков наилучший способ сделать этот анализ с использованием потоков? - PullRequest
0 голосов
/ 11 октября 2019

Я хотел знать, как мы можем выполнить приведенный ниже анализ чисто с помощью потоков. Здесь я пытаюсь изменить Список карт в Карты Карт. Я выполняю синтаксический анализ, как показано ниже

Ввод:

[ 
   { 
      "productId":1,
      "price":2,
      "noOfBuyers":6
   },
   { 
      "productId":2,
      "price":5,
      "noOfBuyers":8
   },
   { 
      "productId":1,
      "rating":5
   }
]

Я хочу объединить сведения о конкретном продукте в одну карту. Я не могу создать объект продукта, так как поля внутри него будут отличаться каждый раз.

Разобрать вышеприведенный json для:

{
   "1" : {
    "productId":1
    "price":2,
    "noOfBuyers":6,
    "rating":5
   },
   "2":{ 
    "productId":2,
    "price":5,
    "noOfBuyers":8
   }

}
private void parseResponse(Map<String, Map<String, Object>> response, List<Map<String, Object>> s) {
     if(s.size() > 0) {
            for (Map<String, Object> maps : s) {
                if (maps != null && maps.containsKey("productId")) {
                    String productId = maps.get("productId").toString();
                    if (!response.containsKey(productId))
                        response.put(productId, maps);
                    else {
                        for (Map.Entry<String, Object> entry: maps.entrySet()) {
                            response.get(productId).put(entry.getKey(), entry.getValue());
                        }
                    }
                }
            }
        }
}

1 Ответ

1 голос
/ 11 октября 2019

ОБНОВЛЕНО: Изменено использование новых образцов данных из обновленного вопроса (версия 5).

Используя потоки, метод может быть реализован следующим образом:

private static Map<String, Map<String, Object>> convertResponse(List<Map<String, Object>> response) {
    return response.stream()
            .filter(maps -> maps != null && maps.containsKey("productId"))
            .collect(Collectors.toMap(maps -> maps.get("productId").toString(),
                                      Function.identity(),
                                      (m1, m2) -> { m1.putAll(m2); return m1; }));
}

Тест

List<Map<String, Object>> response = List.of(
        new HashMap<>(Map.of("productId", 1, "price", 2, "noOfBuyers", 6)),
        new HashMap<>(Map.of("productId", 2, "price", 5, "noOfBuyers", 8)),
        new HashMap<>(Map.of("productId", 1, "rating", 5)));
System.out.println(response);

Map<String, Map<String, Object>> converted = convertResponse(response);
System.out.println(converted);

Выход

[{productId=1, noOfBuyers=6, price=2}, {productId=2, noOfBuyers=8, price=5}, {rating=5, productId=1}]
{1={rating=5, productId=1, noOfBuyers=6, price=2}, 2={productId=2, noOfBuyers=8, price=5}}

Из комментария:

Вариант использования таков, что мне нужно внести изменения в карту ответов, которую я посылаю в качестве параметра в функцию. Допустим, эта функция используется параллельным запущенным API, который получает данные, используйте эту функцию для добавления данных в этот ответ.

Если этот метод вызывается параллельным работает apis, тогда он должен быть потокобезопасным, а код в вопросе не является потокобезопасным.

Для обеспечения полной безопасности потока карта response должна быть одновременной картой,Если это так, код может быть реализован с использованием потоков следующим образом (хотя он на самом деле не использует потоки слишком долго, и с тем же успехом мог бы остаться в цикле for):

private static void parseResponse(Map<String, Map<String, Object>> response, List<Map<String, Object>> s) {
    s.stream()
     .filter(maps -> maps != null && maps.containsKey("productId"))
     .forEach(maps ->
        response.merge(maps.get("productId").toString(),
                       new HashMap<>(maps),
                       (m1, m2) -> {
                           Map<String, Object> merged = new HashMap<>(m1);
                           merged.putAll(m2);
                           return merged;
                       }));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...