Java Notes

Home首页 / Lesson 6: HashMap methods第 6 课:HashMap 方法

Lesson 6 · Use it第 6 课 · 拿来用

HashMap methods, and how they look in real codeHashMap 的常用方法,以及它们在真实代码里长什么样

Six methods cover almost everything: put, get, getOrDefault, computeIfAbsent, merge, remove.六个方法能盖住几乎所有场景:put、get、getOrDefault、computeIfAbsent、merge、remove。

Short answer先给答案Six methods cover almost everything: put (add or replace), get (read), getOrDefault (read with a default), computeIfAbsent (compute and store only if missing), merge (combine old and new), remove (delete).六个方法基本够用:put 存或覆盖;get 读;getOrDefault 读不到给默认值;computeIfAbsent 没有才算并存入;merge 合并新旧值;remove 删除。

Basics基础HashMapHashMapreal code真实代码

01The six methods六个方法

Method方法What it does做什么Where I use it我用在哪
put(k,v)add or replace添加或覆盖save a value by key按 key 存一个值
get(k)read, null if missing读,没有则返回 nullsimple lookup简单查询
getOrDefault(k,d)read, d if missing读,没有就给默认值counters, optional config计数、可选配置
computeIfAbsent(k,f)compute and store only if missing没有才算并存入cache, grouping缓存、分组
merge(k,v,f)combine old and new合并新旧值sum, max, join求和、取最大、拼接
remove(k)delete删除clear, cancel清理、取消

02Real code: a cache真实代码:缓存

// 没有就查数据库,再放进缓存(最常见的写法)
User user = cache.computeIfAbsent(userId, id -> userMapper.selectById(id));

One line: read the cache, miss → query the database → write back. No null check, no two lookups.一行:读缓存,没命中——查库——写回。不用判空,也不用查两次。

In a real service add an expiry (Caffeine or Redis). computeIfAbsent keeps the map small, but it never forgets.真实服务里还要加过期(Caffeine 或 Redis)。computeIfAbsent 只是让它懒加载,但不会自己忘。

03Real code: counting真实代码:计数

// 统计每个状态有多少单
Map count = new HashMap<>();
for (Order o : orders) {
    count.merge(o.getStatus(), 1, Integer::sum);
}

merge is the cleanest counter: old value + 1, or 1 if it is the first time.merge 是最干净的计数写法:老值 +1,第一次出现就给 1。

04Real code: grouping真实代码:分组

// 按用户分组:Map>
Map> byUser = new HashMap<>();
for (Order o : orders) {
    byUser.computeIfAbsent(o.getUserId(), k -> new ArrayList<>()).add(o);
}

Or with the stream API: orders.stream().collect(Collectors.groupingBy(Order::getUserId)) — it does the same thing internally.也可以用 stream:orders.stream().collect(Collectors.groupingBy(Order::getUserId)),内部做的就是同一件事。

05Four things that bite四个坑

→New words新词

HashMap /hæʃ mæp/ Map by key, built on an array of buckets.HashMap:用桶数组实现的键值表 ▶ hear it
entry /ˈentri/ One key-value pair.entry:一个键值对 ▶ hear it
cache /kæʃ/ A small fast copy of slow data.缓存:慢数据的一份快速副本 ▶ hear it
merge /mɜːrdʒ/ Combine two values.merge:合并两个值 ▶ hear it
grouping /ˈɡruːpɪŋ/ Putting items into groups by a field.分组:按字段归类 ▶ hear it

Click ▶ hear it for real people on YouGlish; 🔊 for the computer voice.点 ▶ hear it 听真人发音(YouGlish);点 🔊 听电脑朗读。

✓Check yourself自测

  1. Difference between get and getOrDefault?get 和 getOrDefault 有什么区别?
  2. Write the one-liner cache with computeIfAbsent.用 computeIfAbsent 写出那一行缓存。
  3. How do you count occurrences cleanly?怎么干净地做计数?

Answer out loud first. Only then open the answers below.先自己出声答,再看下面的答案。

Answers参考答案
01get returns null when the key is missing; getOrDefault returns the default you pass.get 没有这个 key 就返回 null;getOrDefault 返回你给的默认值。
02`cache.computeIfAbsent(id, k -> db.selectById(k))` — one line, no null check.`cache.computeIfAbsent(id, k -> db.selectById(k))`——一行,不用判空。
03`count.merge(status, 1, Integer::sum)` — old + 1, or 1 the first time.`count.merge(status, 1, Integer::sum)`——老值 +1,第一次出现就给 1。

Next: Lesson 7, threads →下一课:第 7 课,线程 →