【问题标题】:Difference between replace and put for HashMapHashMap的replace和put的区别
【发布时间】:2021-09-22 16:37:42
【问题描述】:

我想使用HashMap 制作直方图,关键应该是延迟,值是延迟发生的次数。如果已经存在的延迟再次出现,我怀疑使用 HashMap replace 或 HashMap put 函数。我是这样做的:

int delay = (int) (loopcount-packetServed.getArrivalTime());
if(histogramType1.containsKey(delay)) {
    histogramType1.replace(delay, histogramType1.get(delay) + 1);   
} else {
    histogramType1.put(delay, 1);
}

这是正确的吗?还是应该使用两倍的 put 函数?

【问题讨论】:

  • Replace "仅当当前映射到某个值时才替换指定键的条目"
  • 所以我应该保留替换解决方案?
  • 在这种情况下应该没关系,因为如果元素存在,它应该具有与put 相同的结果 - 因为使用了containsKey replace 仅在存在映射时才被调用.
  • 我希望键保持不变,但附加到该键的值应该增加 1,我认为使用 put 函数会导致键的 2 倍附加不同的值它。
  • 不,地图不允许重复键,因此调用 put 而不是 replace 也会导致旧值被删除。

标签: java replace hashmap


【解决方案1】:

在您的情况下,由于您首先检查该值是否包含在地图中,因此使用 put 或 replace 会导致相同的结果。

您可以使用其中任何一种,具体取决于您更容易阅读的内容。

【讨论】:

    【解决方案2】:

    当存在所需密钥的当前映射时,put 和 replace 绝对没有区别。来自replace:

    仅当当前映射到某个值时才替换指定键的条目。

    这意味着如果给定键已经存在映射,put 和 replace 将以相同的方式更新映射。两者还将返回与键关联的先前值。但是,如果该键没有映射,则 replace 将是无操作(不会执行任何操作),而 put 仍将更新映射。


    从 Java 8 开始,注意你可以直接使用

    histogramType1.merge(delay, 1, Integer::sum);
    

    这将照顾每一个条件。来自merge:

    如果指定的键尚未与值关联或与null 关联,则将其与给定的非空值关联。否则,将关联的值替换为给定重映射函数的结果,如果结果为 null,则删除。

    在这种情况下,如果条目不存在,我们将创建条目 delay -> 1。如果确实存在,则通过将值增加 1 来更新它。

    【讨论】:

      【解决方案3】:

      如果您查看源代码,您会看到以下内容(这是来自更新 11,但可能没有太大变化):

      替换:

      if ((e = getNode(hash(key), key)) != null) {
          V oldValue = e.value;
          e.value = value;
          afterNodeAccess(e);
          return oldValue;
      }    
      

      put(内部方法putVal):

      //some code before this to find the node e (similar to getNode(hash(key)))
      if (e != null) { // existing mapping for key
         V oldValue = e.value;
         if (!onlyIfAbsent || oldValue == null)  //onlyIfAbsent is false here
           e.value = value;
         afterNodeAccess(e);
         return oldValue;
      }
      

      如您所见,代码的相关部分基本上做同样的事情,因为 onlyIfAbsent 对 put 是错误的,因此总是会替换该值。

      【讨论】:

        【解决方案4】:

        您可以通过以下方式验证其他人描述的行为:

        public class Main {
            public static void main(String[] args) {
                Map<String, String> map = new HashMap<>();
                map.replace("a", "1");
                System.out.println(map.get("a"));
        
                map.put("a", "1");
                System.out.println(map.get("a"));
        
                map.replace("a", "2");
                System.out.println(map.get("a"));
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-12
          • 2012-06-05
          • 1970-01-01
          • 2012-04-28
          • 2019-02-19
          • 2011-02-15
          • 2020-10-11
          相关资源
          最近更新 更多