【问题标题】:Difference between Map.put and Map.putAll methods?Map.put 和 Map.putAll 方法的区别?
【发布时间】:2011-08-14 13:04:49
【问题描述】:

Map.putAll 相当于在指定映射中从键 k 到值 v 的每个映射调用一次映射上的 Map.put(k, v)。因此,在功能方面,两者都是相同的。

所以,我很想知道其他区别是什么以及何时使用哪一个?

【问题讨论】:

    标签: java dictionary collections interface


    【解决方案1】:

    好吧,这取决于。

    putputAll 是接口方法,因此 每个 该接口的实际实现将保证 put 方法在映射中放置一个键/值对,而 @987654324 @ 将放置源中的所有键/值对。

    但这取决于实施者如何执行它以及另外(内部)做什么。

    当然,一个简单的实现会为源映射的每个条目调用put,但也许有人发明了另一种方法来实现目标。或者putAll 会在输入添加对之前/之后/同时做一些其他的地图内部工作。

    我的经验法则是:如果您必须将所有键/值对从一个映射放到另一个映射,则依赖实现者的聪明才智并使用putAll 方法。它总是很有可能比手动为所有对调用 put 提供更好的性能。

    【讨论】:

      【解决方案2】:

      如文档中所述:

      Map.put

      将指定的值与 此映射中的指定键 (可选操作)。如果地图 以前包含一个映射 键,旧值被替换为 指定值。 (地图 m 被称为 如果和 只有当 m.containsKey(k) 会返回 真的。)

      允许您将单个键值对放入映射中。

      Map.putAll

      从 指定映射到此映射(可选 手术)。这个调用的效果是 相当于调用 put(k, v) 每个映射在这张地图上一次 从指定的键 k 到值 v 地图。此操作的行为是 如果指定的地图是未定义的 在操作进行时修改 进展。

      将所有数据从一张地图放到另一张地图。


      什么时候用哪个?

      如果您想将完整数据从一个映射复制到另一个映射,您可以使用map.putAll,否则您只需使用map.put 添加一个键值对。


      Map.putAll 等价于 在地图上调用 Map.put(k, v) 一次 对于从键 k 到值 v 的每个映射 在指定的地图中。所以随着 功能方面都是一样的。

      不,当您在 hasmap 中实现 map 时,使用 put(k,v) 将一个映射复制到另一个会花费更多的精力,您可以说使用 putAll(m) 进行更多编码,我们可以使用单行代码复制 map。

      【讨论】:

        【解决方案3】:

        当您有一个包含多个值的 Map 要添加到 Map 时使用 putAll(Map),当您有一个或几个值要添加到 Map 时使用 put(K,V)

        putAll(Map) 在大多数实现中只是在循环中调用put(K,V),读取source

        【讨论】:

        • 最后一行有点误导。尽管 AbstractMap 确实 像您描述的那样工作,但其他具体的 Map 实现却没有。
        • @Paul:+1,你是对的。这有点简化,但我相信大多数符合 Map 接口的实现都是这样工作的,因为 Map 接口并没有给那么多余地。
        【解决方案4】:

        由于 Map 只是一个接口,没有任何实现,因此 putAll 和重复 put 之间没有任何区别,除了您所说的功能方面。换句话说:不可能有任何区别。但是,如果您查看 Map 的各个实现(例如 HashMap),性能可能会有所不同。对于任何合理的实现,一个 putAll 至少应该与重复 put 一样有效,但它可能完全相同。

        【讨论】:

        • +1 - 你打败了我......你回答了 OP 的问题,而不仅仅是背诵 API 细节。
        【解决方案5】:

        最明显的区别是同步集合。

        对于同步映射,putAll 会将所有条目添加为单个操作。如果你有两个线程试图把所有相同的键放入不同的值,你只会得到一组完整的值。即来自第一个或第二个线程,但不是某种组合。

        如果你在两个线程中重复使用 put(),你可以得到任意组合的值被保留,这可能不是一个有效的组合。


        我已经看到/实现了 put() 和 putAll() 的事务操作。当 putAll 是事务性的时,将添加所有或不添加键/值。例如如果由于某种原因无法添加键或值。如果您使用 put(),则只会停止单个键/值(可能还有任何未添加的键/值),执行可能不完整的更新。

        【讨论】:

          【解决方案6】:

          使用 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.上面提到Map是一个接口,所以性能取决于实现,我考虑过HashMap,因为它被广泛使用。 因此,如果性能是一个限制因素,您至少可以将 putAll() 用于 HashMap。

          【讨论】:

            【解决方案7】:

            putAll( ) method

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

            put( ) method

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

            【讨论】:

              【解决方案8】:

              Map.put(Object key, Object value) 允许您将单个条目添加到 Map.putAll(Map t) 将 Map t 中包含的所有条目添加到指定的 Map。 putAll() 在组合两个 Map 时很有用。

              【讨论】:

                猜你喜欢
                • 2019-05-26
                • 1970-01-01
                • 2011-11-10
                • 1970-01-01
                • 2016-01-31
                • 2013-06-12
                • 1970-01-01
                • 2017-12-02
                • 1970-01-01
                相关资源
                最近更新 更多