【问题标题】:update existing key of HashMap更新 HashMap 的现有键
【发布时间】:2019-06-28 09:44:53
【问题描述】:

我有长度为 3 的 HashMap

1=>"Value1"
2=>"Value2"
3=>"Value3"

现在我想将所有键减 1(如果键>1): 输出:

1=>"Value2"
2=>"Value3"

我正在尝试什么

  for (e in hashMap.entries) {
                                val entry = e as Map.Entry<*, *>
                                var keyPos = (entry.key as Int)
                                if (keyPos != -1) {
                                    if (keyPos > 1) {
                                        keyPos = keyPos - 1
                                        if (keyPos != -1) {
                                            hashMap.put(keyPos, entry.value as String?)
                                        }
                                    }
                                }
                            }

但它没有提供所需的输出。

如何让它在没有并发异常的情况下工作。

【问题讨论】:

  • 使用两张地图,创建一个与众不同的副本
  • 你试过Iterator吗?
  • 在for里面使用迭代器会产生并发异常
  • 您无法更新Map 密钥,您只能删除旧密钥并使用新密钥插入其值。
  • 或者你可以先获取第三个键的值,然后更新第二个键的值

标签: java android kotlin concurrency hashmap


【解决方案1】:

另一种方法是使用mapKeys 扩展函数,它允许您重新定义映射条目的键:

fun main() {
    val originalMap = mapOf(1 to "value1", 2 to "value2", 3 to "value3")
    val updatedMap = originalMap
        .mapKeys {
            if (it.key > 1) {
                it.key - 1
            } else {
                it.key
            }
        }

    println(updatedMap) // prints: {1=value2, 2=value3}
}

请注意,这不会就地更新地图,但会创建一个新地图。另请注意:

如果任何两个条目映射到相等的键,则后一个的值将覆盖与前一个关联的值。

这意味着如果两个键发生冲突,通常您无法知道哪个会“获胜”(除非您使用的是 LinkedHashMap,它保留了插入顺序)。

更通用的方法是:

  1. 递减所有键
  2. 过滤掉所有非正键

不过,这将需要 2 次完整的迭代(除非您使用 Sequences,它们会被延迟评估):

fun main() {
    val originalMap = mapOf(1 to "value1", 2 to "value2", 3 to "value3")
    val updatedMap = originalMap
        .mapKeys {
            it.key - 1
        }.filter {
            it.key > 0
        }

    println(updatedMap)
}

【讨论】:

    【解决方案2】:

    编辑:这里与 Java 7 兼容代码相同(无流)

    HashMap<Integer, String> hashMap = new HashMap<>();
    hashMap.put(1, "test1");
    hashMap.put(2, "test2");
    hashMap.put(3, "test3");
    
    Map<Integer, String> yourNewHashMap = new HashMap<>();
    for (final Map.Entry<Integer, String> entry : hashMap.entrySet()) {
        if (entry.getKey() != 1) { // make sure index 1 is omitted
            yourNewHashMap.put(entry.getKey() - 1, entry.getValue()); // decrease the index for each key/value pair and add it to the new map
        }
    }
    


    流的旧答案:

    由于您可以使用新的地图对象,因此我将使用以下流: cmets 是内联的

    HashMap<Integer, String> hashMap = new HashMap<>();
    hashMap.put(1, "test1");
    hashMap.put(2, "test2");
    hashMap.put(3, "test3");
    
    // use this
    Map<Integer, String> yourNewHashMap = hashMap.entrySet().stream()
                                           .filter(es -> es.getKey() != 1) // make sure index 1 is omitted
                                           .map(es -> new AbstractMap.SimpleEntry<Integer, String>(es.getKey() - 1, es.getValue())) // decrease the index for each key/value pair
                                           .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)); // create a new map
    

    【讨论】:

      【解决方案3】:
      public static void main(String[] args) {
          HashMap<Integer, String> map = new HashMap<>();
      
          // Populate the HashMap
          map.put(1, "Value1");
          map.put(2, "Value2");
          map.put(3, "Value3");
          System.out.println("Original HashMap: "
                  + map); 
          decreaseAllKeysByOne(map);
      }
      
      private static void decreaseAllKeysByOne(HashMap<Integer, String> map) {
          // Add your condition (if key>1)
          HashMap<Integer, String> newMap = new HashMap<>();
          map.remove(1);
      
      
          Iterator<Map.Entry<Integer, String>> iterator = map.entrySet().iterator();
          int i = 1;
          while (iterator.hasNext()) {
              Map.Entry<Integer, String> entry = iterator.next();
              newMap.put(i, entry.getValue());
              i++;
          }
          System.out.println("Modified HashMap: "
                  + newMap);
      }
      

      输出:

      原始 HashMap:{1=Value1, 2=Value2, 3=Value3}

      修改后的 HashMap:{1=Value2, 2=Value3}

      【讨论】:

        猜你喜欢
        • 2011-10-09
        • 2018-10-15
        • 2021-04-11
        • 1970-01-01
        • 1970-01-01
        • 2016-02-07
        • 1970-01-01
        • 2020-06-26
        • 2021-06-22
        相关资源
        最近更新 更多