Как предотвратить переопределение одним и тем же ключом Hashmap с разными значениями - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть код, подобный следующему, где я использую хэш-карту для хранения деталей созданных сегментов, но Hashmap переопределяет последнее значение для всех ключей.

, но ответ, который я получаю, выглядит следующим образом

0->47 {id=48 name= At_48,code=14512455......}
1->48 {id=48 name= At_48,code=14512455......}

Я получаю все ответы, переопределенные последним результатом, как решить эту проблему

Ответы [ 3 ]

0 голосов
/ 16 сентября 2018

Это поведение по умолчанию для хэш-карты: не важно, перезаписать ли вы значения ключа, которые использовались ранее. Карта - это просто контейнер, откуда ему знать, что вы не хотите перезаписывать предыдущие значения ?!

Если вам нужно что-то еще, есть два варианта:

  • вы расширяете этот класс и @Override пут (), чтобы проверить использование уже известного ключа
  • ваш клиентский код, который заполняет карту, проверяет наличие ключа, прежде чем сделать вызов put ()

Но учтите: тогда вам понадобится четкая стратегия, как справляться с ситуациями, когда на карту уже было добавлено другое значение. Одним из решений может быть сделать значение карты списком. И помещение значений для известного ключа приводит к: новое значение добавляется в список.

0 голосов
/ 16 сентября 2018

Извините, люди, я до сих пор не могу публиковать только комментарии, у вас проблема в том, что хеш-метод, который вы используете для генерации ключа, не должен возвращать тот же хеш-код, вся идея хеширования утратила смысл, если два значения разделенытот же ключ.изменить метод генератора ключей.

привет!

0 голосов
/ 16 сентября 2018

Вы используете в каждой итерации одно и то же segmentInformation. Таким образом, это единственное значение в returnMap, введенное для каждого ключа.

Вам нужно создать новый SegmentInformation на каждом шаге итерации и поместить его на карту. Проблема, которую вы указали в своем комментарии, заключается в том, что вы используете segmentInformation уже перед циклом for. Это только в случае, если audienceDataMap.isEmpty(). Я предлагаю вам отделить этот код от кода цикла.

  private Single<Map<String, CreationResponse>> createSegment(List<Integer> audienceIds) {
    try {
      createToken();
    }
    catch (ValidationServiceException e) {
      SegmentInformation segmentInformation = new SegmentInformation();
      segmentInformation.setError(SEGMENT_CREATION_EXCEPTION.getMessage());
      Map<String, CreationResponse> returnMap = new HashMap<>();
      returnMap.put(segmentInformation.getAudienceId().toString(), segmentInformation);
      logger.error(TOKEN_CREATION_EXCEPTION.getMessage());
    }
    catch (IOException e) {
      SegmentInformation segmentInformation = new SegmentInformation();
      segmentInformation.setError(SEGMENT_CREATION_EXCEPTION.getMessage() + SEGMENT_CODE_EXIST.getMessage());
      Map<String, CreationResponse> returnMap = new HashMap<>();
      returnMap.put(segmentInformation.getAudienceId().toString(), segmentInformation);
      logger.error(SEGMENT_CREATION_EXCEPTION.getMessage());
    }

    List<ListBasedAudienceFetcher.AcAudience> audienceDataMap = audienceIds != null ?
      impl.processAudienceByIds(audienceIds) :
      impl.processAudience();

    if (audienceDataMap.isEmpty()) {
      SegmentInformation segmentInformation = new SegmentInformation();
      segmentInformation.setError(PROGRAMS_NOT_CREATED.getMessage());
      Map<String, CreationResponse> returnMap = new HashMap<>();
      returnMap.put(CREATE_PROGRAM.getMessage(), segmentInformation);
      return Single.just(returnMap);
    }

    Map<String, CreationResponse> returnMap = new HashMap<>();
    for (ListBasedAudienceFetcher.AcAudience audienceData : audienceDataMap) {
      SegmentInformation segmentInformation = new SegmentInformation();
      segmentInformation.setMemberId(memberId);
      segmentInformation.setAudienceId(audienceData.getId());
      String audienceName = getSegmentName(audienceData);
      segmentInformation.setAudienceName(audienceName);
      try {
        String createSegmentResponse = Util.post(new PayLoad()
          .setUrl(AppNexusConstants.APPNEXUS_SEGMENT_URL + "/" + memberId)
          .setRequestType(Request.POST)
          .setHeader(getAppnexusAuthHeader())
          .setPayload(createSegmentPayload(audienceData, memberId)));
        SegmentResponse segmentResponse = Util.mapper.readValue(createSegmentResponse, SegmentResponse.class);
        if (segmentResponse != null
          && segmentResponse.getResponse().getStatus() != null
          && segmentResponse.getResponse().getStatus().equals("OK")) {
          BillingData billingData = billingSegment(audienceData, segmentResponse.getResponse().getSegmentData());
          segmentResponse.getResponse().getSegmentData().setBillingData(billingData);
        } else {
          segmentInformation.setError(SEGMENT_CREATION_EXCEPTION.getMessage() + audienceData.getId());
        }
        segmentInformation.setSegmentCreationResponses(segmentResponse);
        returnMap.put(audienceData.getId().toString(), segmentInformation);
      }
      catch (IOException e) {
        segmentInformation.setError(SEGMENT_CREATION_EXCEPTION.getMessage() + SEGMENT_CODE_EXIST.getMessage());
        returnMap.put(segmentInformation.getAudienceId().toString(), segmentInformation);
        logger.error(SEGMENT_CREATION_EXCEPTION.getMessage());
      }
    }

    return Single.just(returnMap);
  }

Обратите внимание, что я также переместил объявление billingData в блок if, где оно инициализировано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...