HashMap возвращается с помощью Maps.newHashMap и нового HashMap

Я впервые пытаюсь использовать Guava, и я считаю, что это действительно потрясающе.

Я выполняю несколько параметризованных запросов на получение в шаблоне Spring jdbc. Метод в DAO (AbstractDataAccessObject) выглядит следующим образом. Здесь нет проблем.

public Map<String,Object> getResultAsMap(String sql, Map<String,Object> parameters) {
    try {
        return jdbcTemplate.queryForMap(sql, parameters);
    } catch (EmptyResultDataAccessException e) {
        //Ignore if no data found for this query
        logger.error(e.getMessage(), e);

    }
    return null;
}

Здесь проблема:

Когда я вызываю этот метод, используя

getResultAsMap(query, new HashMap<String,Object>(ImmutableMap.of("gciList",gciList)));

он отлично работает.

Но когда я это делаю,

getResultAsMap(query, Maps.newHashMap(ImmutableMap.of("gciList",gciList)));

компилятор расстраивается, говоря

The method getResultAsMap(String, Map<String,Object>) in the type AbstractDataAccessObject is not applicable for the arguments (String, HashMap<String,List<String>>)

Я делаю что-то неправильно или что может быть причиной этой жалобы?

Ответ 1

Это ошибка ввода типа. Maps.newHashMap - статический параметризованный метод. Это позволяет использовать

Map<String,Integer> map = Maps.newHashMap()

вместо

Map<String,Integer> map = new HashMap<String,Integer>()

избавляет вас от необходимости вводить <String,Integer> дважды. В Java 7 оператор алмаза позволяет использовать

Map<String,Integer> map = new HashMap<>()

поэтому метод будет лишним.

Чтобы ответить на ваш вопрос, просто используйте версию new HashMap, так как вывод типа не работает для параметров метода. (Вы можете использовать Maps.<String,Object>newHashMap(), но это побеждает точку использования метода)

Ответ 2

Проблема в том, что ваш метод принимает Map<String, Object>, но это не то, что вы хотите. Вы хотите использовать Map из String для любых значений. Это не Map<String, Object>, это Map<String, ?>.

Ответ 3

Добавление позднего ответа здесь:

Большая часть преимуществ уходит до того, как вывод типа появился в java. (yay), но мне было интересно узнать о каких-либо различиях в производительности. Вот код для google.common.collect.maps

  /**
   * Creates a <i>mutable</i>, empty {@code HashMap} instance.
   *
   * <p><b>Note:</b> if mutability is not required, use {@link
   * ImmutableMap#of()} instead.
   *
   * <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link
   * #newEnumMap} instead.
   *
   * @return a new, empty {@code HashMap}
   */
  public static <K, V> HashMap<K, V> newHashMap() {
    return new HashMap<K, V>();
  }

Его тот же код.

Ответ 4

Обновление: я неправильно прочитал ошибку компилятора - извините! Не стесняйтесь удалять мой ответ!

Каков точный тип "Карты" - это действительно java.util.Map и точный тип HashMap - это действительно java.util.HashMap? Здесь, кажется, есть несоответствие.

Оригинальный ответ: Очевидно, Maps.newHashMap возвращает реализацию интерфейса карты, которая неизвестна, однако для getResultAsMap требуется HashMap (что является необычным требованием). getResultAsMap следует реорганизовать, чтобы вместо этого использовать интерфейс, а не конкретную реализацию.