当前位置:首页 > 数码 > Java-基于红黑树成功-TreeMap底层成功原理 (java基础知识点)

Java-基于红黑树成功-TreeMap底层成功原理 (java基础知识点)

admin6个月前 (05-14)数码28

阿里这段期间忙着制订下半年的OKR,其真实制订OKR的时刻就能看出团队里谁是指导的嫡系,谁是团队的边角料。嫡系的OKR都是从指导的外围名目分进去的,而其他人的OKR不会体如今指导的OKR外面,只配给嫡系做打下手的任务。

员工的绩效,在制订OKR的时刻,曾经确定了。

职场失意,摸鱼自得。我还是忧心的降级《解读源码专栏》,在这个系列中,我将手把手带着大家剖析Java外围组件的源码,内容蕴含汇合、线程、线程池、并发、队列等,深化了解其面前的设计思维和成功细节,轻松应答任务面试。这是解读Java源码系列的第六篇,将跟大家一同窗习Java中比拟不凡的数据结构-。

引言

上篇文章讲到 LinkedHashMap 可以保障元素的拔出顺序或许访问顺序,而也能保障元素顺序,不过依照键的顺序启动排序。拔出到中的键值对,会智能依照键的顺序启动排序。

简介

底层结构是基于数组成功的,而底层结构是基于红黑树成功的。应用红黑树的个性成功对键的排序。额外引见一下红黑树的个性:

红黑树是基于平衡二叉树的改良,而平衡二叉树是为了处置二叉搜查树在不凡状况下,退步成链表,查找、拔出效率退步成O(n),规则左右子树高度差不超越1,然而拔出、删除节点的时刻,所做的平衡操作比拟复杂。而红黑树的个性,保障了平衡操作成功相对繁难,树的高度仅比平衡二叉树高了一倍,查找、拔出、删除的期间复杂度是O(logn)。

经常使用示例

应用可以智能对键启动排序的个性,比拟适用一些须要排序的场景,比如排行榜、商品列表等。

Map<Integer,String>map=newTreeMap<>();map.put(1,"One");map.put(3,"Three");map.put(2,"Two");System.out.println(map);//输入:{1=One,2=Two,3=Three}

成功一个繁难的热词排行榜性能:

/***@author一灯架构*@apiNote热词**/publicclassHot{/***热词内容*/Stringword;/***热度*/Integercount;publicHotWord(Stringword,Integercount){this.word=word;this.count=count;}}
importjava.util.Comparator;importjava.util.TreeMap;/***@author一灯架构*@apiNote热词排行榜**/publicclassLeaderboard{/***自定义排序形式,依照热度降序陈列*/privatestaticfinalComparator<HotWord>HOT_WORD_COMPARATOR=newComparator<HotWord>(){@Overridepublicintcompare(HotWordo1,HotWordo2){returnInteger.compare(o2.count,o1.count);//降序陈列}};//经常使用TreeMap存储排行榜数据,key是热词对象,value是热词题目privateTreeMap<HotWord,String>rankMap=newTreeMap<>(HOT_WORD_COMPARATOR);//参与效果publicvoidaddHotWord(Stringname,intscore){rankMap.put(newHotWord(name,score),name);}/***打印排行榜*/publicvoidprintLeaderboard(){System.out.println("热词排行榜:");intrank=1;for(HotWordhotWord:rankMap.keySet()){System.out.println("#"+rank+""+hotWord);rank++;}}publicstaticvoidmn(String[]args){Leaderboardleaderboard=newLeaderboard();leaderboard.addHotWord("闲鱼崩了",90);leaderboard.addHotWord("淘宝崩了",95);leaderboard.addHotWord("闲鱼崩了",85);leaderboard.addHotWord("钉钉崩了",80);leaderboard.printLeaderboard();}}

输入结果:

热词排行榜:#1HotWord(word=淘宝崩了,count=95)#2HotWord(word=闲鱼崩了,count=90)#3HotWord(word=闲鱼崩了,count=85)#4HotWord(word=钉钉崩了,count=80)

类属性

看一下TreeMap的类属性,蕴含哪些字段?

publicclassTreeMap<K,V>extendsAbstractMap<K,V>implementsNavigableMap<K,V>,Cloneable,java.io.Serializable{/***排序形式*/privatefinalComparator<?superK>comparator;/***红黑树根节点*/privatetransientEntry<K,V>root;/***红黑树节点数*/privatetransientintsize=0;/***红黑树的红黑节点示意*/privatestaticfinalbooleanRED=false;privatestaticfinalbooleanBLACK=true;/***红黑树节点对象*/staticfinalclassEntry<K,V>implementsMap.Entry<K,V>{Kkey;Vvalue;Entry<K,V>left;Entry<K,V>right;Entry<K,V>parent;booleancolor=BLACK;/***结构方法*/Entry(Kkey,Vvalue,Entry<K,V>parent){this.key=key;this.value=value;this.parent=parent;}}}

TreeMap类属性比拟繁难,蕴含排序形式comparator、红黑树根节点root、节点个数size等。自定义了一个红黑树节点类Entry,外部属性包括键值对、左右子树、父节点、红黑标志值等。

初始化

TreeMap罕用的初始化形式有上方三个:

/***无参初始化*/Map<Integer,Integer>map1=newTreeMap<>();/***指定排序形式初始化*/Map<Integer,Integer>map2=newTreeMap<>(newComparator<Integer>(){@Overridepublicintcompare(Integero1,Integero2){returno1.compareTo(o2);}});/***将个别Map转换为TreeMap*/Map<Integer,Integer>map3=newTreeMap<>(newHashMap<>());

再看一下对应的源码成功:

/***无参初始化*/publicTreeMap(){comparator=null;}/***指定排序形式初始化*/publicTreeMap(Comparator<?superK>comparator){this.comparator=comparator;}/***将个别Map转换为TreeMap*/publicTreeMap(Map<?extendsK,?extendsV>m){comparator=null;putAll(m);}

方法列表

由于TreeMap存储是依照键的顺序陈列的,所以还可以启动范围查问,上方举一些示例。

importjava.util.Collections;importjava.util.Map;importjava.util.TreeMap;/***@author一灯架构*@apiNoteTreeMap方法测试*/publicclassTreeMapTest{publicstaticvoidmain(String[]args){//1.创立一个热词排行榜(按热度倒序),key是热度,value是热词内容TreeMap<Integer,String>rankMap=newTreeMap<>(Collections.reverrder());rankMap.put(80,"阿里云崩了");rankMap.put(100,"淘宝崩了");rankMap.put(90,"钉钉崩了");rankMap.put(60,"闲鱼崩了");rankMap.put(70,"支付宝崩了");System.out.println("热词排行榜:");for(Map.Entry<Integer,String>entry:rankMap.entrySet()){System.out.println("#"+entry.getKey()+""+entry.getValue());}System.out.println("-----------");//2.失掉排行榜的第一个元素Map.Entry<Integer,String>firstEntry=rankMap.firstEntry();System.out.println("firstEntry:"+firstEntry);//3.失掉排行榜的最后一个元素Map.Entry<Integer,String>lastEntry=rankMap.lastEntry();System.out.println("lastEntry:"+lastEntry);//4.失掉排行榜的大于指定键的最小元素(由于是倒序陈列,所以结果是反的)Map.Entry<Integer,String>higherEntry=rankMap.higherEntry(70);System.out.println("higherEntry:"+higherEntry);//5.失掉排行榜的小于指定键的最大元素Map.Entry<Integer,String>lowerEntry=rankMap.lowerEntry(70);System.out.println("lowerEntry:"+lowerEntry);//6.失掉排行榜的大于等于指定键的最小元素Map.Entry<Integer,String>ceilingEntry=rankMap.ceilingEntry(70);System.out.println("ceilingEntry:"+ceilingEntry);//7.失掉排行榜的小于等于指定键的最大元素Map.Entry<Integer,String>floorEntry=rankMap.floorEntry(70);System.out.println("floorEntry:"+floorEntry);}}

输入结果:

热词排行榜:#100淘宝崩了#90钉钉崩了#80阿里云崩了#70支付宝崩了#60闲鱼崩了-----------firstEntry:100=淘宝崩了lastEntry:60=闲鱼崩了higherEntry:60=闲鱼崩了lowerEntry:80=阿里云崩了ceilingEntry:70=支付宝崩了floorEntry:70=支付宝崩了

其余方法的还包括:

TreeMap底层成功原理
作用 方法签名
失掉第一个键 KfirstKey()
失掉最后一个键 KlastKey()
失掉大于指定键的最小键 KhigherKey(Kkey)
失掉小于指定键的最大键 KlowerKey(Kkey)
失掉大于等于指定键的最小键 KceilingKey(Kkey)
失掉小于等于指定键的最大键 KfloorKey(Kkey)
失掉第一个键值对 Map.Entry<K,V>firstEntry()
失掉最后一个键值对 Map.Entry<K,V>lastEntry()
失掉并删除第一个键值对 Map.Entry<K,V>pollFirstEntry()
失掉并删除最后一个键值对 Map.Entry<K,V>pollLastEntry()
失掉大于指定键的最小键值对 Map.Entry<K,V>higherEntry(Kkey)
失掉小于指定键的最大键值对 Map.Entry<K,V>lowerEntry(Kkey)
失掉大于等于指定键的最小键值对 Map.Entry<K,V>ceilingEntry(Kkey)
失掉小于等于指定键的最大键值对 Map.Entry<K,V>floorEntry(Kkey)
失掉子map,左闭右开 SortedMap<K,V>subMap(KfromKey,KtoKey)
失掉前几个子map,不蕴含指定键 SortedMap<K,V>headMap(KtoKey)
失掉前几个子map NavigableMap<K,V>headMap(KtoKey,booleaninclusive)
失掉后几个子map,不蕴含指定键 SortedMap<K,V>tailMap(KfromKey)
失掉后几个子map NavigableMap<K,V>tailMap(KfromKey,booleaninclusive)
失掉其中一段子map NavigableMap<K,V>subMap(KfromKey,booleanfromInclusive,KtoKey,booleantoInclusive)

put源码

再看一下的put源码:

/***put源码入口*/publicVput(Kkey,Vvalue){Entry<K,V>t=root;//1.假设根节点为空,则创立根节点if(t==null){compare(key,key);root=newEntry<>(key,value,null);size=1;modCount++;returnnull;}intcmp;Entry<K,V>parent;//2.判别能否传入了排序形式,假设没有则经常使用自动Comparator<?superK>cpr=comparator;if(cpr!=null){//3.假设传入了排序形式,经常使用do-while循环,找到指标值所在位置,并赋值do{parent=t;cmp=cpr.compare(key,t.key);//4.应用红黑树节点左小右大的个性,启动查找if(cmp<0){t=t.left;}elseif(cmp>0){t=t.right;}else{returnt.setValue(value);}}while(t!=null);}else{//5.TreeMap不准许key为nullif(key==null){thrownewNullPointerException();}//6.假设没有传入排序形式,则经常使用Comparable启动比拟Comparable<?superK>k=(Comparable<?superK>)key;//7.跟上方分歧,经常使用do-while循环,应用红黑树节点左小右大的个性,查找指标值所在位置,并赋值do{parent=t;cmp=k.compareTo(t.key);if(cmp<0){t=t.left;}elseif(cmp>0){t=t.right;}else{returnt.setValue(value);}}while(t!=null);}//8.假设没有找到,则创立新节点Entry<K,V>e=newEntry<>(key,value,parent);if(cmp<0){parent.left=e;}else{parent.right=e;}//9.拔出新节点后,须要调整红黑树节点位置,坚持红黑树的个性fixAfterInsertion(e);size++;modCount++;returnnull;}

put源码逻辑比拟繁难:

get源码

再看一下get源码:

/***get源码入口*/publicVget(Objectkey){//调用查找节点的方法Entry<K,V>p=getEntry(key);return(p==null?null:p.value);}/***查找节点方法*/finalEntry<K,V>getEntry(Objectkey){//1.判别假设传入了排序形式,则经常使用排序形式查找节点if(comparator!=null){returngetEntryUsingComparator(key);}if(key==null){thrownewNullPointerException();}//2.否则经常使用自动形式查找Comparable<?superK>k=(Comparable<?superK>)key;Entry<K,V>p=root;//3.应用红黑树节点左小右大的个性,循环查找while(p!=null){intcmp=k.compareTo(p.key);if(cmp<0){p=p.left;}elseif(cmp>0){p=p.right;}else{returnp;}}returnnull;}/***经常使用传入的排序形式,查找节点方法*/finalEntry<K,V>getEntryUsingComparator(Objectkey){Kk=(K)key;Comparator<?superK>cpr=comparator;if(cpr!=null){Entry<K,V>p=root;//3.跟上方相似,应用红黑树节点左小右大的个性,循环查找while(p!=null){intcmp=cpr.compare(k,p.key);if(cmp<0){p=p.left;}elseif(cmp>0){p=p.right;}else{returnp;}}}returnnull;}

get方法源码与put方法逻辑相似,都是应用红黑树的个性遍历红黑树。

总结

是一种有序Map汇合,具备以下个性:


Java 容器详解:使用与案例

深入解析Java的容器世界:探索、实践与案例

Java的容器,如同一个精致的工具箱,承载着数据和对象的管理。与C++的STL类相比,Java Collection Framework (JCF) 提供了更为丰富的功能和灵活性。让我们一起探索这个框架,理解Collection和Map的核心概念,以及它们在实际项目中的应用。

一、Java容器概览

二、设计模式的应用

Java容器巧妙地运用了设计模式,如迭代器模式。Collection接口的iterator()方法生成一个Iterator,让我们能够遍历集合中的元素,从JDK 1.5开始,foreach语句让遍历变得更简洁。

三、源码解析实战

让我们通过ArrayList和Vector的源码,了解它们的内部结构和关键操作,如ArrayList的动态扩容、删除和序列化机制。同时,学习Vector的同步机制和CopyOnWriteArrayList的读写分离特性。

四、容器的内存优化与选择

理解不同容器的内存管理策略,如LinkedList的链表结构、HashMap的拉链法和WeakHashMap的弱引用,对内存敏感和性能要求高的场景尤为重要。CopyOnWriteArrayList在读多写少场景中表现出色,但需要权衡内存消耗和数据一致性。

五、总结与建议

掌握Java容器不仅是入门,深入理解其内部原理和算法是提升编程技能的关键。通过查阅API和源码,亲手实现容器,能让你在实际开发中游刃有余。选择合适的容器,根据项目需求定制数据结构,将极大提升代码质量和效率。

学习Java容器,让我们在数据管理的旅程中更加自信和熟练。

java map容器 哪些排序

一.理论准备Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等。 TreeMap:基于红黑树(Red-Black tree)的 NavigableMap 实现,该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。 HashMap的值是没有顺序的,它是按照key的HashCode来实现的,对于这个无序的HashMap我们要怎么来实现排序呢?参照TreeMap的value排序。 返回Collections视图。 二排序TreeMap默认是升序的,如果我们需要改变排序方式,则需要使用比较器:Comparator。 Comparator可以对集合对象或者数组进行排序的比较器接口,实现该接口的public compare(T o1,To2)方法即可实现排序,如下:import ;import ;import ;import ;import ;public class TreeMapTest {public static void main(String[] args) {Map<String, String> map = new TreeMap<String, String>(new Comparator<String>() {public int compare(String obj1, String obj2) {// 降序排序return (obj1);}});(b, ccccc);(d, aaaaa);(c, bbbbb);(a, ddddd);Set<String> keySet = ();Iterator<String> iter = ();while (()) {String key = ();(key + : + (key));}}}运行结果如下:d:aaaaac:bbbbbb:ccccca:ddddd三排序上面例子是对根据TreeMap的key值来进行排序的,但是有时我们需要根据TreeMap的value来进行排序。 对value排序我们就需要借助于Collections的sort(List<T> list, Comparator<? super T> c)方法,该方法根据指定比较器产生的顺序对指定列表进行排序。 但是有一个前提条件,那就是所有的元素都必须能够根据所提供的比较器来进行比较,如下:import ;import ;import ;import ;import ;import ;import ;public class TreeMapTest {public static void main(String[] args) {Map<String, String> map = new TreeMap<String, String>();(a, ddddd);(c, bbbbb);(d, aaaaa);(b, ccccc);//这里将()转换成listList<<String,String>> list = new ArrayList<<String,String>>(());//然后通过比较器来实现排序(list,new Comparator<<String,String>>() {//升序排序public int compare(Entry<String, String> o1,Entry<String, String> o2) {return ()(());}});for(<String,String> mapping:list){(()+:+());}}}运行结果如下:d:aaaaac:bbbbbb:ccccca:ddddd

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: Java

“Java-基于红黑树成功-TreeMap底层成功原理 (java基础知识点)” 的相关文章

深入探讨-Java-编程中的类继承与接口实现 (深入探讨交流)

深入探讨-Java-编程中的类继承与接口实现 (深入探讨交流)

简介 类索引、父类索引和接口索引是在 Class 文件中用于确定类的继承关系的重要数据。通过这些索引,Java 虚拟机 (JVM) 可以准确地建立类之间的继承关系,实现多态性和接口的实现。...

大编程趋势-5-年-Java-2024-开发者的 (编程是大趋势吗)

大编程趋势-5-年-Java-2024-开发者的 (编程是大趋势吗)

Java 作为编程领域的支柱,拥有超过 900 万开发人员和超过 30 年的发展历史。它以其先进的安全功能、优越的性能和跨平台开发能力而闻名。展望 2024 年,Java 正准备进行一场突破性的转...

Java中不倡导经常使用foreach的六大场景 (java中不等于怎么写)

Java中不倡导经常使用foreach的六大场景 (java中不等于怎么写)

在中,foreach是一个罕用的循环结构,它可以极大地简化遍历数组或汇合(例如List或Set)的代码。它通常被以为是一种愈加繁复和易读的迭代形式。但是,或许有一些状况下不倡导经常使用foreac...

Java-渣滓回收器的运作形式-对不再沉闷对象的跟踪机制

Java-渣滓回收器的运作形式-对不再沉闷对象的跟踪机制

作为一门面向对象的编程言语,具备智能内存治理的个性。这象征着开发人员无需手动调配和监禁内存,而是由Java虚构机的渣滓回收器担任治理。渣滓回收器经过监督程序中不再经常使用的对象来回收内存,以提高内...

掌握Java并发编程-免除竞态条件的困扰 (掌握JavaScript基础)

掌握Java并发编程-免除竞态条件的困扰 (掌握JavaScript基础)

1. 竞态条件的概念和问题 竞态条件指的是多个线程同时访问共享资源,由于执行顺序的不确定性,导致程序结果与预期不符的情况。竞态条件问题通常出现在以下情况下: 多个线程争用同一把锁 多个线程...

Java-以及如何成功它-为何它本应更繁难-异步编程 (java一个子类可以有多个父类吗)

Java-以及如何成功它-为何它本应更繁难-异步编程 (java一个子类可以有多个父类吗)

在过去的好多年里,多线程和异步不时作为技术里的初级局部,在技术序列中,一个言语分为入门局部、进阶局部和初级局部,所以,异步是作为其中的初级技术局部存在的。 关于异步和多线程这局部吧,经常存在...

Java-三分钟速成-揭秘多线程编程新范式-虚拟线程 (java三目表达式)

Java-三分钟速成-揭秘多线程编程新范式-虚拟线程 (java三目表达式)

背景 虚拟线程是 Java 语言中的一种轻量级线程,可以减少编写、维护和调试高吞吐量并发应用程序的工作量。虚拟线程的详细背景介绍可以在 JEP 444 中找到。 平台线程...

Java废品回收器对循环引用对象的处理机制 (java废弃方法)

Java废品回收器对循环引用对象的处理机制 (java废弃方法)

循环引用的定义和问题 循环引用是指两个或多个对象之间形成了相互引用的关系,形成了一个环状结构。例如,对象 A 引用了对象 B,而对象 B 又引用了对象 A,它们之间形成了一个循环引用。在这种情况...