LinkedHashMap 一些示例、BigDecimal
BigDecimalJava 专门用来存金额、小数、财务数字的类型double/float会出现精度丢失算钱绝对不能用所以营收、订单金额一律用BigDecimalBigDecimal.ZEROBigDecimal类自带的静态常量代表数字 0是已经提前创建好的0对象。等价于new BigDecimal(0)但好处不用每次new新对象节省内存代码规范、可读性强开发统一写法。配套常用三个常量BigDecimal.ZERO→ 0BigDecimal.ONE→ 1BigDecimal.TEN→ 10LinkedHashMap 实战场景案例先牢记两个核心特性默认插入有序put先后顺序遍历就什么顺序传第三个参数true访问有序get/put过后元素排末尾做LRU缓存专用一、简单场景日常写接口天天碰到案例1下拉枚举字典固定顺序展示最常用需求前端页面角色下拉框必须按顺序超级管理员 → 运营 → 财务 → 普通用户HashMap存放遍历顺序随机前端下拉选项顺序会乱必须用LinkedHashMappublicMapString,IntegergetRoleOptions(){MapString,IntegerroleMapnewLinkedHashMap();// 按展示顺序依次存入roleMap.put(超级管理员,1);roleMap.put(运营人员,2);roleMap.put(财务人员,3);roleMap.put(普通用户,4);returnroleMap;}返回给前端JSONkey-value永远保持存入顺序下拉列表不会错乱。案例2IN查询自定义ID顺序要保留需求前端勾选了一批订单ID105, 22, 78, 9要查询这几个订单详情返回列表严格按照这个ID顺序排列MySQL执行select * from order where id in (105,22,78,9)数据库查询出来的数据顺序是主键从小到大不会遵从你in括号里的顺序。解决办法先把前端传来的ID数组遍历循环查询到的订单以id为key放入LinkedHashMap最终遍历map顺序完全和前端勾选顺序一致。// 前端传来的顺序数组ListLongidListArrays.asList(105L,22L,78L,9L);// 数据库查出所有符合条件的订单顺序乱的ListOrderdbOrderListorderMapper.selectBatchIds(idList);// 1. 存入HashMap做快速查找MapLong,OrdertempMapnewHashMap();for(Ordero:dbOrderList){tempMap.put(o.getId(),o);}// 2. 按照前端原始顺序放入LinkedHashMap保证最终有序MapLong,OrderresultMapnewLinkedHashMap();for(Longid:idList){if(tempMap.containsKey(id)){resultMap.put(id,tempMap.get(id));}}// 遍历resultMap105 → 22 → 78 → 9 严格有序案例3导出Excel表头列固定先后顺序导出Excel表格表头列序号、姓名、手机号、地址、创建时间表头集合必须固定顺序用 LinkedHashMap 存储 表头key 和 列宽导出时循环遍历绘制列列不会颠倒。二、中等复杂度场景BigDecimalJava 专门用来存金额、小数、财务数字的类型double / float 会出现精度丢失算钱绝对不能用所以营收、订单金额一律用 BigDecimal BigDecimal.ZEROBigDecimal类自带的静态常量代表数字 0是已经提前创建好的0对象。等价于new BigDecimal(0)但好处不用每次new新对象节省内存代码规范、可读性强开发统一写法。配套常用三个常量BigDecimal.ZERO→ 0BigDecimal.ONE→ 1BigDecimal.TEN→ 10案例4接口多维度统计数据按时间段有序返回需求统计近7天每日营收key是日期字符串2026-07-24 ~ 2026-07-30返回前端必须从早到晚依次排列方案先循环生成7天日期依次put进LinkedHashMap初始营收0用SQL查出每一天实际营收回填map最终遍历出来天然是时间先后顺序不用额外排序。// 初始化7天时间有序容器MapString,BigDecimaldayIncomenewLinkedHashMap();dayIncome.put(2026-07-24,BigDecimal.ZERO);dayIncome.put(2026-07-25,BigDecimal.ZERO);dayIncome.put(2026-07-26,BigDecimal.ZERO);dayIncome.put(2026-07-27,BigDecimal.ZERO);dayIncome.put(2026-07-28,BigDecimal.ZERO);dayIncome.put(2026-07-29,BigDecimal.ZERO);dayIncome.put(2026-07-30,BigDecimal.ZERO);// 只查出有营收的那些天数据ListDayStatstatListstatMapper.select7DayIncome();// 循环把查到的真实营收回填到map中覆盖原来的0for(DayStatitem:statList){// key日期 value当日收入dayIncome.put(item.getDay(),item.getIncome());}// 返回前端日期永远从前往后排序查询结果 假设数据库只查到3天有收入24号100元、26号200元、30号500元 循环回填之后map内部数据1.2026-07-24→1002.2026-07-25→03.2026-07-26→2004.2026-07-27→05.2026-07-28→06.2026-07-29→07.2026-07-30→500对比用HashMap的话日期顺序完全打乱前端还要自己排序。案例5接口日志参数记录保存请求参数插入顺序接收前端表单一堆参数姓名、年龄、住址、邮箱、备注需要把所有参数原样有序存储到日志里方便排查问题用LinkedHashMap接收请求参数保留用户提交顺序。三、复杂场景框架底层、缓存开发、面试高频案例6自定义本地LRU内存缓存最经典用途需求本地缓存热门商品详情最多存放10条数据超过10条时自动删掉最久没有访问过的商品释放内存。依靠 LinkedHashMap 访问顺序特性 重写淘汰规则实现不用自己维护链表/** * LRU本地缓存最多存10个元素 */publicclassGoodsCacheextendsLinkedHashMapLong,Goods{// 初始容量、负载因子、true开启访问排序publicGoodsCache(){super(16,0.75f,true);}// 重写方法返回true代表删除最久未使用的元素OverrideprotectedbooleanremoveEldestEntry(Map.EntryLong,Goodseldest){// 缓存容量大于10触发淘汰returnsize()10;}}使用GoodsCachecachenewGoodsCache();// 存入15个商品自动删掉最早没访问的5个for(longi1;i15;i){cache.put(i,newGoods(i,商品i));}cache.get(3L);// 访问3号商品3被挪到链表末尾最晚被淘汰适用场景小型项目无Redis本地临时缓存热点数据Redis底层、MyBatis二级缓存底层都大量借鉴这个思路。案例7路由规则有序匹配权限系统场景后台权限拦截器配置多条URL拦截规则需要从上到下依次匹配/api/login 放行/api/register 放行/api/admin/** 需要管理员权限/** 需要登录认证规则有优先级顺序必须从上往下遍历匹配HashMap无序无法实现只能LinkedHashMap存储规则。四、哪些场景绝对不要用 LinkedHashMap单纯存取数据、不需要任何顺序HashMap性能更高内存开销更小需要根据key大小升序/降序排列TreeMap多线程并发读写缓存线程不安全要用 ConcurrentHashMap百万级大数据存储不适合放内存。一句话选型口诀要保留存入顺序、遍历顺序固定 → LinkedHashMap其余普通存取 → HashMap需要自动按键排序 → TreeMap多线程并发 → ConcurrentHashMap