Skip to content

Map的使用与代码题常用场景详解


一、Map是什么?

Map是Java集合框架中的接口,用于存储键值对(Key-Value) 数据。每个键(Key)唯一对应一个值(Value),类似字典结构。核心实现类:

  • HashMap:无序,基于哈希表(JDK8后引入红黑树优化冲突)
  • LinkedHashMap:保留插入顺序
  • TreeMap:按键自然排序
  • ConcurrentHashMap:线程安全(JDK8后改用CAS+synchronized)

二、解决什么问题

  1. 快速查找:通过键(Key)直接定位值(Value),时间复杂度接近O(1)
  2. 数据关联:建立两个数据集的映射关系(如用户ID→用户信息)
  3. 去重计数:利用Key的唯一性实现统计(如词频统计)

三、核心方法

方法说明
put(K key, V value)添加键值对
get(Object key)根据Key获取Value
containsKey(Object key)判断Key是否存在
keySet()返回所有Key的集合
entrySet()返回所有键值对的集合
getOrDefault(K key, V defaultValue)Key不存在时返回默认值(JDK8新增)
computeIfAbsent(K key, Function f)Key不存在时通过函数生成Value(JDK8新增)

四、代码题常用场景

  1. 频率统计

    java
    // 统计字符串中字符出现次数
    Map<Character, Integer> freq = new HashMap<>();
    for (char c : s.toCharArray()) {
        freq.put(c, freq.getOrDefault(c, 0) + 1);
    }
  2. 索引映射

    java
    // 两数之和:用Map存储<数值, 索引>
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement)) {
            return new int[]{map.get(complement), i};
        }
        map.put(nums[i], i);
    }
  3. 缓存最近访问(LRU)

    java
    // 使用LinkedHashMap实现LRU缓存
    Map<Integer, String> cache = new LinkedHashMap<>(16, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return size() > MAX_SIZE;
        }
    };
  4. 分组聚合

    java
    // 按学生班级分组(JDK8 Stream API)
    Map<String, List<Student>> groupByClass = students.stream()
        .collect(Collectors.groupingBy(Student::getClassName));

五、Java示例:单词计数器

java
import java.util.*;

public class WordCounter {
    public static void main(String[] args) {
        String text = "apple banana apple orange banana apple";
        Map<String, Integer> counter = new HashMap<>();
        
        // JDK8增强:合并计数
        Arrays.stream(text.split(" "))
              .forEach(word -> counter.merge(word, 1, Integer::sum));
        
        // 输出:{orange=1, banana=2, apple=3}
        System.out.println(counter); 
    }
}

六、与类似结构的区别

结构特点适用场景
MapKey-Value映射,Key唯一需通过Key快速查找Value
Set仅存储Key(基于Map实现)元素去重
List有序集合,可重复按索引访问

七、重要注意事项

  1. 键对象需重写hashCode()equals()
    (否则HashMap无法正确识别Key)
  2. HashMap线程不安全
    并发场景用ConcurrentHashMapCollections.synchronizedMap()
  3. 避免在迭代中修改Map
    会抛出ConcurrentModificationException
  4. 初始容量与负载因子
    java
    // 预估数据量1000,负载因子0.75
    new HashMap<>(1333, 0.75f); // 容量=1000/0.75≈1333

八、总结

Map是解决关联性数据存储的核心工具,在代码题中常用于:

  1. 快速查找(如两数之和)
  2. 频率统计(如字符计数)
  3. 分组聚合(如按类别分组)
  4. 缓存实现(如LRU缓存)

掌握HashMap的核心机制(哈希冲突、红黑树优化)及JDK8新增方法(getOrDefaultcomputeIfAbsent),能显著提升解题效率。建议在算法练习中优先考虑Map解决映射类问题。