杰瑞科技汇

HashMap核心方法有哪些?

我们将从以下几个方面来详细介绍 HashMap 的方法:

HashMap核心方法有哪些?-图1
(图片来源网络,侵删)
  1. 核心方法:最常用、最基本的方法。
  2. 批量操作方法:用于处理多个键值对。
  3. 视图方法:获取 HashMap 的不同“视图”。
  4. 辅助方法:获取容量、大小等信息。
  5. 哈希相关方法:理解其内部工作原理的关键。
  6. Java 8+ 新增方法:利用 Lambda 表达式进行更简洁的编程。

核心方法

这些方法是日常开发中使用频率最高的。

V put(K key, V value)

  • 功能:将指定的键值对存入此映射中。

  • 返回值

    • 如果之前该键已经存在,则返回之前与该键关联的旧值。
    • 如果键不存在,则返回 null
  • 示例

    HashMap核心方法有哪些?-图2
    (图片来源网络,侵删)
      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95); // 返回 null
      scores.put("Bob", 88);   // 返回 null
      Integer oldScore = scores.put("Alice", 98); // 返回旧的值 95
      System.out.println("Alice's new score: " + scores.get("Alice")); // 输出 98
      System.out.println("Old score was: " + oldScore); // 输出 95

V get(Object key)

  • 功能:返回指定键所映射的值。

  • 返回值

    • 如果找到键,返回对应的值。
    • 如果键不存在,返回 null
    • 注意value 本身就是 nullget(key) 返回 null 无法区分是键不存在还是值是 null,此时需要用 containsKey(key) 来判断。
  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      System.out.println("Alice's score: " + scores.get("Alice")); // 输出 95
      System.out.println("Charlie's score: " + scores.get("Charlie")); // 输出 null

V remove(Object key)

  • 功能:从此映射中移除指定键的映射关系(如果存在)。

    HashMap核心方法有哪些?-图3
    (图片来源网络,侵删)
  • 返回值

    • 如果键存在,返回被移除的值。
    • 如果键不存在,返回 null
  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      Integer removedScore = scores.remove("Alice"); // 返回 95
      System.out.println("Removed score: " + removedScore); // 输出 95
      System.out.println("Is Alice still in the map? " + scores.containsKey("Alice")); // 输出 false

boolean containsKey(Object key)

  • 功能:如果此映射包含指定键的映射关系,则返回 true

  • 用途:用于安全地检查一个键是否存在,避免因 get() 返回 null 而产生歧义。

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      if (scores.containsKey("Alice")) {
          System.out.println("Alice is in the map.");
      }

boolean containsValue(Object value)

  • 功能:如果此映射将一个或多个键映射到指定值,则返回 true
  • 注意:此方法的性能通常比 containsKey() 差,因为它需要遍历所有值。

boolean isEmpty()

  • 功能:如果此映射不包含键值映射关系,则返回 true

int size()

  • 功能:返回此映射中的键值映射关系数。

批量操作方法

这些方法用于一次性执行多个操作,非常高效。

void putAll(Map<? extends K, ? extends V> m)

  • 功能:将指定映射 m 中的所有映射关系复制到此映射中。

  • 示例

      Map<String, Integer> map1 = new HashMap<>();
      map1.put("A", 1);
      Map<String, Integer> map2 = new HashMap<>();
      map2.put("B", 2);
      map2.put("C", 3);
      map1.putAll(map2); // map1 现在包含 A, B, C

void clear()

  • 功能:从此映射中移除所有映射关系,此调用返回后,映射将为空。

视图方法

视图方法是 HashMap 功能强大的体现,它们提供了对 HashMap 内部数据结构的访问,并且是动态的,即当 HashMap 发生变化时,视图也会随之变化。

Set<K> keySet()

  • 功能:返回此映射中包含的键的 Set 视图。

  • 用途:可以遍历所有的键,或者通过该 Set 来删除键。

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      scores.put("Bob", 88);
      Set<String> names = scores.keySet();
      for (String name : names) {
          System.out.println(name); // 输出 Alice, Bob (顺序不确定)
      }
      // 通过视图删除
      names.remove("Alice"); // 这会从原始的 HashMap 中移除 "Alice"

Collection<V> values()

  • 功能:返回此映射中包含的值的 Collection 视图。

  • 用途:可以遍历所有的值。

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      scores.put("Bob", 88);
      Collection<Integer> allScores = scores.values();
      for (Integer score : allScores) {
          System.out.println(score); // 输出 95, 88 (顺序不确定)
      }

Set<Map.Entry<K, V>> entrySet()

  • 功能:返回此映射中包含的键值映射关系的 Set 视图。Map.Entry 是一个表示单个键值对的接口。

  • 用途:这是最强大的视图,因为它允许你同时访问键和值,推荐在需要遍历整个映射时使用 entrySet(),因为它比先遍历 keySet() 再通过 get() 获取值的效率更高。

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      scores.put("Bob", 88);
      for (Map.Entry<String, Integer> entry : scores.entrySet()) {
          String name = entry.getKey();
          Integer score = entry.getValue();
          System.out.println(name + ": " + score);
      }

辅助方法

Object clone()

  • 功能:创建此 HashMap 实例的浅拷贝。
  • 注意:它创建了一个新的 HashMap 对象,并复制了所有键值对,键和值对象本身没有被复制,新映射和旧映射共享这些对象,这是一个浅拷贝

哈希相关方法

理解这些方法有助于理解 HashMap 的工作原理。

int hashCode()

  • 功能:返回此映射的哈希码值。HashMap 内部会维护一个哈希码,用于快速判断两个 HashMap 是否可能相等。
  • 实现:哈希码是其所有条目的哈希码的异或 (^) 总和。

boolean equals(Object o)

  • 功能:将指定对象与此映射进行比较,以判断它们是否相等。
  • 规则:两个 HashMap 相等,当且仅当它们包含相同的键值对,且两个键 k1k2 满足 (k1==null ? k2==null : k1.equals(k2)),两个值 v1v2 也满足相同的条件。

Java 8+ 新增方法

Java 8 引入的 Lambda 表达式和 Stream API,让 HashMap 的操作更加简洁和强大。

V getOrDefault(Object key, V defaultValue)

  • 功能:返回指定键映射到的值,如果该映射不包含该键的映射关系,则返回 defaultValue

  • 优点:比 get() + containsKey() 的组合更简洁。

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      // scores.put("Alice", 95); // 假设 Alice 不存在
      int score = scores.getOrDefault("Alice", 0); // 如果不存在,返回默认值 0
      System.out.println("Score: " + score); // 输出 0

V putIfAbsent(K key, V value)

  • 功能:如果指定的键尚未映射到值,则将其映射到给定的值。

  • 返回值:返回与 key 关联的先前值,key 没有映射关系,则返回 null

  • 用途:线程安全的原子操作(在单线程环境下可以优雅地避免重复计算或覆盖)。

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      // Alice 不存在,才设置值为 100
      scores.putIfAbsent("Alice", 100); // Alice 已存在,此操作无效,返回 95
      scores.putIfAbsent("Bob", 88);    // Bob 不存在,设置成功,返回 null
      System.out.println(scores); // 输出 {Alice=95, Bob=88}

boolean remove(Object key, Object value)

  • 功能:仅当指定键当前映射到指定值时,才移除该条目。

  • 返回值:如果移除成功,返回 true;否则返回 false

  • 用途:精确删除,避免误删。

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      boolean removed1 = scores.remove("Alice", 100); // key存在但value不匹配,返回 false
      boolean removed2 = scores.remove("Alice", 95);  // key和value都匹配,返回 true
      System.out.println(removed1); // false
      System.out.println(removed2); // true
      System.out.println(scores.isEmpty()); // true

void replace(K key, V oldValue, V newValue)

  • 功能:仅当指定键当前映射到指定值时,才替换该条目。

  • 返回值:无 (void)。

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      scores.replace("Alice", 95, 100); // 替换成功
      scores.replace("Bob", 88, 90);   // Bob不存在,不执行任何操作
      System.out.println(scores); // 输出 {Alice=100}

V replace(K key, V value)

  • 功能:仅当指定键当前映射到某个值时,才替换该条目。

  • 返回值:返回与 key 关联的先前值,key 没有映射关系,则返回 null

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      Integer oldVal = scores.replace("Alice", 100); // 返回 95
      Integer newVal = scores.replace("Bob", 88);    // Bob不存在,返回 null
      System.out.println(oldVal); // 95
      System.out.println(newVal); // null

void forEach(BiConsumer<? super K, ? super V> action)

  • 功能:对此映射中的每个条目执行给定的操作,直到所有条目都被处理或操作引发异常。

  • 优点:代码更简洁,无需手动迭代。

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      scores.put("Bob", 88);
      scores.forEach((name, score) -> System.out.println(name + " scored " + score));

void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)

  • 功能:将对此映射中的每个条目替换为对该条目调用给定函数的结果。

  • 用途:批量更新所有值。

  • 示例

      Map<String, Integer> scores = new HashMap<>();
      scores.put("Alice", 95);
      scores.put("Bob", 88);
      // 将所有分数加 5
      scores.replaceAll((name, oldScore) -> oldScore + 5);
      System.out.println(scores); // 输出 {Alice=100, Bob=93}

V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)

  • 功能:如果指定的键尚未与值关联或与 null 关联,则将其与给定的非 null 值关联,否则,用给定的重新映射函数对该键的当前值及其给定值进行计算,并用结果替换该值。

  • 用途:非常强大,可以优雅地处理值的合并逻辑,例如列表的累加、计数等。

  • 示例

      Map<String, List<String>> userRoles = new HashMap<>();
      // 如果用户不存在,创建一个新列表;如果存在,将新角色添加到现有列表中
      userRoles.merge("Alice", Arrays.asList("ADMIN"), (oldList, newRoleList) -> {
          oldList.addAll(newRoleList);
          return oldList;
      });
      userRoles.merge("Alice", Arrays.asList("USER"), (oldList, newRoleList) -> {
          oldList.addAll(newRoleList);
          return oldList;
      });
      System.out.println(userRoles.get("Alice")); // 输出 [ADMIN, USER]

V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)

  • 功能:尝试计算指定键及其当前映射的映射关系(如果有的话)。

  • 用途:根据键和旧值计算一个新值,可以用于添加、更新或删除条目。remappingFunction 返回 null,则该条目将被移除。

  • 示例

      Map<String, Integer> counts = new HashMap<>();
      // key 不存在,oldValue 为 null
      counts.compute("apple", (k, oldVal) -> oldVal == null ? 1 : oldVal + 1);
      counts.compute("apple", (k, oldVal) -> oldVal + 1); // 再次计算
      System.out.println(counts); // 输出 {apple=2}

V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)

  • 功能:如果指定的键尚未与值关联或与 null 关联,则尝试使用给定的映射函数计算其值,并将其输入到此映射中,除非 null

  • 用途:延迟初始化或计算一个值,避免不必要的计算。

  • 示例

      Map<String, Integer> counts = new HashMap<>();
      // 只有当 "banana" 不存在时,才会执行 lambda 表达式
      counts.computeIfAbsent("banana", k -> k.length()); // k.length() 返回 6
      System.out.println(counts); // 输出 {banana=6}

V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)

  • 功能:如果指定键的当前映射值不为 null,则尝试在给定键及其当前映射值的情况下运行给定的重新映射函数,除非该值为 null

  • 用途:仅在键存在且值不为 null 时才进行计算。

  • 示例

      Map<String, Integer> counts = new HashMap<>();
      counts.put("cherry", 5);
      // 只有当 "cherry" 存在且值不为 null 时,才会执行 lambda
      counts.computeIfPresent("cherry", (k, oldVal) -> oldVal * 2);
      counts.computeIfPresent("mango", (k, oldVal) -> oldVal * 2); // mango 不存在,不执行
      System.out.println(counts); // 输出 {cherry=10}
方法类别 核心方法 描述
基本操作 put(), get(), remove() 添加、获取、删除单个键值对。
查询 containsKey(), containsValue(), isEmpty(), size() 检查映射内容。
批量操作 putAll(), clear() 复制或清空整个映射。
视图 keySet(), values(), entrySet() 提供对键、值、键值对的动态访问视图。
Java 8+ getOrDefault(), putIfAbsent(), remove(), replace() 原子操作,避免竞态条件。
Java 8+ forEach(), replaceAll(), merge(), compute() 函数式编程,简化代码,实现复杂逻辑。

掌握这些方法,特别是 Java 8 引入的函数式方法,将极大地提高你使用 HashMap 的效率和代码的简洁性。

分享:
扫描分享到社交APP
上一篇
下一篇