Разница между методами Map.put и Map.putAll?

Map.putAll эквивалентен вызову Map.put(k, v) на карте один раз для каждого отображения из ключа k в значение v на указанной карте. Таким образом, с функциональным аспектом оба они одинаковы.

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

Ответ 1

Смотря как.

put и putAll являются интерфейсными методами, поэтому каждая реальная реализация этого интерфейса гарантирует, что метод put на карту putAll пару ключ/значение, а putAll поместит все пары ключ/значение из источника.

Но это до разработчика, как это сделать и что делать дополнительно (внутренне).

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

Мое эмпирическое правило таково: если вам нужно поместить все пары ключ/значение из одной карты в другую, тогда положитесь на сообразительность разработчика и используйте метод putAll. Всегда есть хороший шанс, что он обеспечивает лучшую производительность, чем вызов put для всех пар вручную.

Ответ 2

Используйте putAll(Map), когда у вас есть Карта нескольких значений, которые вы хотите добавить на свою Карту, и используйте put(K,V), когда у вас есть один или несколько значений, которые вы хотите добавить на свою карту.

putAll(Map) в большинстве реализаций просто вызывает put(K,V) в цикле, читайте источник.

Ответ 3

Как указано в документах:

Map.put

Связывает указанное значение с указанный ключ на этой карте (дополнительная операция). Если карта ранее содержало отображение для ключ, старое значение заменяется на указанное значение. (Отображение m называется содержат отображение для ключа k, если и только если m.containsKey(k) вернется верно.)

Позволяет поместить на карту одну пару ключ-значение.

Map.putAll

Копирует все сопоставления из указанная карта к этой карте (необязательно операция). Эффект этого вызова эквивалентно вызову put (k, v) на этой карте один раз для каждого отображения от ключа k до значения v в указанном карта. Поведение этой операции undefined, если указанная карта изменено во время операции прогресс.

поместите все данные с одной карты на другую карту.


когда использовать какой?

Если вы хотите скопировать полные данные с одной карты на другую, вы можете использовать map.putAll else, вы можете просто добавить одну пару "ключ-значение", используя map.put.


Map.putAll эквивалентно таковому вызов Map.put(k, v) на карте один раз для каждого отображения из ключа k в значение v в указанной карте. Таким образом, с функциональный аспект одинаковый.

Нет, когда вы реализуете карту в hasmap, затем копируете одну карту в другую, используя put (k, v), приложите больше усилий, и вы можете сказать больше кода, используя putAll (m), мы можем скопировать карту с помощью одного кода строки.

Ответ 4

Так как Map - это просто интерфейс, без какой-либо реализации, не может быть никакой разницы между putAll и повторным помещением, отличным от функциональной разности, т.е. none. Если вы посмотрите на отдельные реализации Map (например, HashMap), может возникнуть проблема с производительностью. Один putAll должен быть, по крайней мере, столь же эффективным, как повторный набор для любой разумной реализации, но он может быть точно таким же.

Ответ 5

Наиболее очевидным отличием является синхронизированная коллекция.

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

Если вы используете put() несколько раз в двух потоках, вы можете получить любую комбинацию сохраняемых значений, которая может быть недействительной.


Я видел/реализовал транзакционные операции для put() и putAll(). Когда putAll является транзакционным, все или никакие ключевые/значения не будут добавлены. например если по какой-либо причине невозможно добавить ключ или значение. Если вы используете put(), только индивидуальный ключ/значение (и, возможно, любой, не добавленный) будет остановлен, выполняя потенциально неполное обновление.

Ответ 6

метод putAll()

Copies all the elements from a specified map to the current Map object.    

метод put()

Adds an element at a specific key entry to a Map object.

Ответ 7

Я вижу огромное преимущество при использовании putAll вместо put. См. Пример программы ниже:

открытый класс SampleTest {

public static void main(final String[] args) {

    final Map<String, String> testMap = new HashMap<>();
    final Map<String, String> testMap2 = new HashMap<>();

    final LocalDateTime startTestTime = LocalDateTime.now();
    for(int i=0; i < 1000000; i++) {
        testMap.put(i+"", i+"");
    }
    final LocalDateTime endTestTime = LocalDateTime.now();
    System.out.println("<<<<<<<<<Time for put>>>>>>>>>>>");
    System.out.println(ChronoUnit.MILLIS.between(startTestTime, endTestTime));

    final LocalDateTime startTestTime1 = LocalDateTime.now();
    testMap2.putAll(testMap);
    final LocalDateTime endTestTime1 = LocalDateTime.now();
    System.out.println("<<<<<<<<<Time for put all>>>>>>>>>>>");
    System.out.println(ChronoUnit.MILLIS.between(startTestTime1, endTestTime1));
}

}

Это возвращает (в миллисекундах):

<<<<<<<<<Time for put>>>>>>>>>>>
1934
<<<<<<<<<Time for put all>>>>>>>>>>>
116

Вывод: putAll() определенно более результативен, чем put() с нижеследующими отказами. 1. Этот результат на моей машине (в зависимости от конфигурации машины). Но вы все еще видите большую разницу. 2. Как указано выше, Карта является интерфейсом, поэтому производительность будет зависеть от реализации, я рассмотрел HashMap, поскольку он широко используется. Поэтому, если производительность является ограничением, вы можете предпочесть putAll() для HashMap по крайней мере.

Ответ 8

Map.put(Object key, Object value) позволяет добавить одну запись во время Map.putAll(Map t) добавляет все записи, содержащиеся в Map t, к указанной карте. putAll() полезен при объединении двух карт.