尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

TreeMap 的使用

TreeMap 的使用 TreeMap 讲解遍历TreeMap1、增强 for 循环兼容全版本通用性最强// 遍历结果按 key 升序1葡萄、2香蕉、5苹果、9橘子for(Map.EntryInteger,Stringentry:map.entrySet()){Integerkeyentry.getKey();Stringvalueentry.getValue();// 业务逻辑System.out.println(序号key水果value);}2、遍历中需删除元素Iterator 迭代器开发注意点 如果需要在遍历过程中删除元素绝对不能用增强for/forEach 否则会抛出ConcurrentModificationException快速失败机制。 必须使用Iterator的remove()方法安全删除IteratorMap.EntryInteger,Stringiteratormap.entrySet().iterator();while(iterator.hasNext()){Map.EntryInteger,Stringentryiterator.next();Integerkeyentry.getKey();// 示例删除序号为2的条目if(key2){iterator.remove();// 安全删除不会触发并发修改异常continue;}System.out.println(序号key水果entry.getValue());}3、仅需Key使用 keySet 遍历如果业务只需要处理所有Key、不需要Value使用keySet()。 ❌ 注意不要用 keySet 遍历反复 map.get(key)取值 每次 get 都会触发一次红黑树查找性能远低于 entrySet。for(Integerkey:map.keySet()){System.out.println(序号key);// 非必要不写String value map.get(key);}4、仅需Value使用 values () 遍历只需要获取所有Value、不关心对应Key时使用。for(Stringfruit:map.values()){System.out.println(水果fruit);}八、一句话总结需要自动按键排序、截取区间、获取前后key→ TreeMap只想要存入顺序不乱 → LinkedHashMap普通存取啥都不需要 → HashMap一、核心本质继承关系TreeMap implements NavigableMap和HashMap无继承关系底层数据结构红黑树自平衡二叉查找树核心特点key 会自动按照规则全局排序不是存入顺序线程不安全key 不允许为 nullvalue 可以null二、排序两种方式开发必用TreeMap 必须规定key怎么排二选一方式1自然排序无参构造new TreeMap()要求存入的key类型 必须实现 Comparable 接口常用自带类型全都实现了Integer、Long、String、Date规则从小到大升序排列示例代码// 无参构造自然排序TreeMapInteger,StringmapnewTreeMap();map.put(5,苹果);map.put(2,香蕉);map.put(9,橘子);map.put(1,葡萄);// 遍历顺序1 → 2 → 5 → 9 按键数字升序for(Map.EntryInteger,Stringentry:map.entrySet()){System.out.println(entry.getKey():entry.getValue());}String排序规则按照ASCII码字典序TreeMapString,IntegermapnewTreeMap();map.put(b,1);map.put(a,2);map.put(c,3);// 输出 a b c⚠️ 坑如果你自定义对象当做key没实现Comparable直接put会直接抛异常ClassCastException方式2定制排序构造传入 Comparator【开发更推荐】不用修改实体类代码排序规则灵活切换优先级高于Comparable语法语法new TreeMap(比较器对象)TreeMap实体类,ObjectmapnewTreeMap(Comparator);案例自定义User对象按年龄降序排列classUser{privateStringname;privateIntegerage;// 构造、get/set省略publicUser(Stringname,Integerage){this.namename;this.ageage;}publicIntegergetAge(){returnage;}OverridepublicStringtoString(){returnname-age;}}publicstaticvoidmain(String[]args){// 比较器年龄 降序ComparatorUsercomparator(u1,u2)-Integer.compare(u2.getAge(),u1.getAge());TreeMapUser,StringtreeMapnewTreeMap(comparator);treeMap.put(newUser(张三,20),员工1);treeMap.put(newUser(李四,35),员工2);treeMap.put(newUser(王五,28),员工3);// 遍历35岁 →28岁 →20岁for(Useruser:treeMap.keySet()){System.out.println(user);}}优势同一个实体类想要升序、降序随时新建比较器就行不用改动实体源码。三、TreeMap独有的强大API这是它不可替代的核心原因因为底层红黑树支持区间查找拥有HashMap、LinkedHashMap没有的方法TreeMapLong,StringmapnewTreeMap();map.put(100L,A);map.put(200L,B);map.put(300L,C);map.put(400L,D);// 1. 获取最小keymap.firstKey();// 100// 2. 获取最大keymap.lastKey();// 400// 3. 小于250的最大key200map.floorKey(250L);// 4. 大于250的最小key300map.ceilingKey(250L);// 5. 截取区间key 200 且 400 的子MapSortedMapLong,Stringsubmap.subMap(200L,401L);// 6. 小于300所有数据map.headMap(300L);// 7. 大于等于300所有数据map.tailMap(300L);只要需要区间截取、上下限查找必须TreeMap四、真实业务使用场景什么时候该用TreeMap场景1按键持续排序 区间数据查询最典型以时间戳Long作为key存储定时任务、排班数据需要查询某段时间范围内所有任务、查询当前时间上一个/下一个排班SQL写起来繁琐内存TreeMap一键调用方法即可。场景2商品价格区间筛选key存商品售价需要快速拿出 100~500元之间所有商品列表。场景3排行榜、计分排序比如积分排行榜key用户积分自动由高到低排序随时拿第一名、前10名。场景4系统固定配置项按编码排序系统字典编码1001、1002、1003…启动加载到内存永久保持升序频繁首尾取值。五、绝对不要用TreeMap的场景单纯存取键值对不需要排序HashMap速度快太多只需要保留插入顺序LinkedHashMap大数据量上万全部载入内存极易OOM排序交给数据库order by多线程并发读写线程不安全六、三大Map核心对比表集合有序类型底层结构查询速度适用场景HashMap无序数组链表红黑树最快日常90%业务存取LinkedHashMap插入/访问有序HashMap双向链表中等固定存入顺序、LRU缓存TreeMapkey自动排序红黑树最慢按键排序、区间查找、首尾取值七、关键注意事项TreeMap判断key相等依靠比较器的返回值不是equals/hashCodekey不能为null否则空指针报错排序规则一旦确定整个容器所有key必须统一类型日常CRUD开发TreeMap使用频率很低大多面试考察红黑树、排序原理。
返回列表