深入源码看JAVA集合的数据结构

这篇我准备从源码的高度来看看集合中各个实现类的是如何组织我们存进去的数据的,主要包括Java类库中提供的几个具体的类: 
LinkedList 
ArrayList 
HashMap 
HashSet 
TreeMap 
TreeSet 
PriorityQueue(顺序按下面的讲解顺序) 


----------------------------------------------------------------------------------------------------- 
1、java.util.LinkedList<E> 
当我们创建一个LinkedList类的对象,并且试图增加一个新的元素的时候,到底是如何组织我们传进去的数据的呢?

Java代码 
 



打开add方法的源码看看: 

Java代码 
 



我们惊喜的发现,原来就是把我们传去的e对象包装成了Entry<E>,然后通过Entry<E>的next和previous两个属性形成了一个以包装后的e对象(即Entry<E>)为节点的双向链表。 
于是我们彻底明白了LinkedList果然名副其实,就是一个链表嘛! 



----------------------------------------------------------------------------------------------------- 
2、java.util.ArrayList<E> 


我们看看在ArrayList对象调用add();方法时,底层到底是如何执行的 

Java代码 
 



于是我们发现:原来ArrayList也是如名字说的,用Array组织数据。不过它内部定义的那个调整elementData数组的方法copy太多,显然当数据量大的时候,性能不会很好。 



----------------------------------------------------------------------------------------------------- 
3、java.util.HashMap<K,V> 

Java代码 
 


想必大家看这段代码都看到晕了吧,为了让大家能够更加形象的人知道HashMap对数据的的组织形式,上了一个HaspMap数据结构图: 

 

这里解释一下,这个图的最左边的一些就是上面源码中的table也就是HashMap的一个属性Entry[] table。将一个新的键值对插入需要经过这几步: 
---给key值计算哈码(计算在这一步int hash = hash(key.hashCode());), 
    ---得出在table数组的中index:int i = indexFor(hash, table. 
length); 
---将键值对插入index确定的上图所示的一个横向的链表中。如果在这个链表中有要插入的pair的key经过hashcode()的一系列运算和equals()的一系列运算相同的元素,就替换原来的value。(这也就是我们自己定义的类要用到HashMap存储的时候,必须重写hashcode()和equals()方法,并且要保证对同一对象两个方法计算结果要相同的原因。因为如果不相同,在一个同一对象为key插入值的时候就不会像你期望的那样后插入的value覆盖前面的value了,而是会重新开辟一个空间存储) 

于是,到这里我们明白了,原来HashMap就是通过散列表这种数据结构组织数据的! 


----------------------------------------------------------------------------------------------------- 
4、java.util.HashSet<E> 

Java代码 
 



小样直接自己不解决,抛给HashMap类的put()方法,也就是用一个散列表存数据。详解见第三条对HashMap的讲解 


----------------------------------------------------------------------------------------------------- 
5、java.util.TreeMap<E> 

Java代码 
 



我们又可以开心的大笑了,原来就是如此简单,就是按照一定的规律形成一棵二叉树来存数据。 
大笑过后,我们再次静下心来观察,源码中出现了这样一句:k.compareTo(t.key);是说用key对应的类中实现的compareTo()方法来判断两个key的先后顺序。有若干标准的java平台类都实现了Compatable接口(Compatator可以自己定义不同的比较规则,不过这个接口的比较规则只有一个,是定义key的类的时候定义的,没有可变性),如String类:

Java代码 
 


所以,我们自己定义key的类的时候,要特别注意compareTo()方法中算法的选择,以便有一个最好的插入、查找、遍历的性能。一般而言将元素添加到树集的速度快于数组和链表,慢于散列表(素服比较:数组、链表<树集<散列表)。 



----------------------------------------------------------------------------------------------------- 
6、java.util.TreeSet<E> 

Java代码 
 


相信大家看到源码立马就能明白了吧,向HashSet一样TreeSet也偷懒了(至于为什么要偷懒,感兴趣的朋友可以去研究,这里不展开了),也是用二叉树的结构存数据,不多说! 



----------------------------------------------------------------------------------------------------- 
7、java.util.PriorityQueue<E> 
(这一条有错,详解见附)

Java代码 
 


一看就明白,就是通过数组组织数据。不过喜欢刨根问底的朋友又会提出一个问题了: 
既然和ArrayList一样都是数组组织数据,那干嘛还要存在这个类呢? 
问的好!继续看: 
PriorityQueue类在数组满了的时候(代码为i >= queue.length),就调用grow(i + 1)这个方法来调整queue的长度。具体调整的算法如下 

Java代码 
 


而ArrayList一上来就调用方法调整了:ensureCapacity(size + 1);里面的具体算法这里就不列出来了。两个类调整的算法不同。这就造成了两者性能上差别。 

tip:好了,今天就分析道这里了。进一步的研究,等过段时间才能出来,到时候再贴出来。时间仓促,难免有漏洞,大家多提意见。 
另外抱怨一下JE的编辑器,真不好用,害得我重新录入! 


纠错:感谢大家能及时反馈给我一些有用的信息,就不一一回复了。就不在原来的文章里改错了,把错误的纠正全写在这后面了,再次感谢! 

----------------------------------------------------------------------------------------------------- 
PriorityQueue<E>重新写了一份: 


我们看看调用add()方法在底层到底发生了什么事情! 

Java代码 
 


嗯,这个类用了一种“堆”(逻辑上是二叉树,存储上用数组,树中的元素有大小关系,越小在数组中的index也越小)的数据结构。 
典型应用是存储有优先级的任务,因为每次调用remove移除最小的元素(优先级最高的元素),都会自动排序,保证每次移除的都是优先级最高的任务。 
同样,TreeMap逻辑上也是通过有序二叉树来组织数据的,不过,TreeMap通过节点的链接来组织存储结构,而PriorityQueue是通过数组的一些列计算确定逻辑上的树的节点的存放位置。 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 事项跟进管理系统是一种高效管理和跟踪任务、项目或事件进展的工具。它可以帮助团队成员协调工作,及时更新进展情况,并提供实时监控和报告功能。 事项跟进管理系统的源码通常使用Java语言编写。它的开发过程需要使用Java编程语言、相关框架和技术来建立系统的后端和前端。 在Java中,可以使用Spring框架来实现事项跟进管理系统的后端逻辑,它提供了面向对象编程的思想和一系列现成的功能模块,以提高开发效率。使用Spring Boot可以快速搭建项目的基础结构,包括配置、依赖管理和构建脚本。 系统的前端可以使用Java的图形界面开发工具,如JavaFX或Swing,来实现用户界面。这些工具提供了丰富的UI组件和功能,可以快速构建用户友好的界面,并与后端进行数据交互。 在源码实现中,需要定义数据库模型,包括事项、用户、项目等实体的关系,以及其属性与操作。使用Java持久层框架,如Hibernate或MyBatis,可以简化数据库访问和操作。通过ORM映射,实现Java对象与数据库表的映射关系,方便持久化数据。 此外,源码还需要处理系统的权限管理、日志记录和异常处理等功能。可以使用Spring Security框架来管理用户的认证和授权,确保系统的安全性。日志记录和异常处理可以使用Java的日志框架,如Log4j或Slf4j,记录系统的运行信息,帮助排查错误和问题。 总之,事项跟进管理系统的源码开发需要使用Java语言和相关技术,通过后端和前端的结合,来实现任务或项目的跟进、管理和监控,提高团队的工作效率和协作能力。 ### 回答2: 事项跟进管理系统是一种用于管理团队中任务、项目或事件进展的软件,它可以帮助团队成员统一获取并共享相关信息,提高工作效率和协作能力。 该系统的源码使用Java语言编写。Java是一种广泛应用于开发企业级应用程序的编程语言,具有跨平台、面向对象、可移植性好等特点。 开发这个系统的源码需要使用Java编程语言和相关开发工具,如Eclipse、IntelliJ IDEA等。在编写源码之前,需要先进行需求分析,明确系统的功能和特性。然后,采用合适的架构模式,如MVC模式,进行系统设计。设计阶段要考虑系统的可扩展性、可维护性和性能等方面。 在编写源码过程中,可以利用Java的各种特性和类库来简化开发工作。比如,使用Java集合类来实现对任务列表的管理,使用多线程技术来处理并发操作,使用数据库连接池和ORM框架来进行数据库操作等。 为了使系统更稳定和安全,还可以使用一些常见的开发框架和组件,如Spring、Hibernate等,并进行相应的配置和调优。 最后,还需要进行测试、调试和部署等工作,确保系统的功能正常且性能符合要求。 总之,事项跟进管理系统的源码可以通过使用Java编程语言和相关工具、框架来实现,以提高团队工作效率和协作能力。 ### 回答3: 事项跟进管理系统是一种用于有效管理工作事项并跟踪进展的系统。它可以帮助组织和团队更好地安排任务、掌握工作进度、提高工作效率。 对于这样的系统,可以用Java编写源码以实现其功能。 首先,我们可以定义一个事项类(Task),其中包含事项的相关属性,如标题、描述、截止日期等。然后,定义一个事项管理类(TaskManager),用于对事项进行管理,包括添加新事项、删除事项、更新事项的状态等。 在项目中,可以设计一个用户界面,用户可以通过界面添加、编辑和删除事项。用户可以输入事项的相关信息,并将其保存到数据库中。此外,还可以实现事项的查看和更新功能,用户可以根据需要更新事项的状态、截止日期或其他属性。 为了更好地跟踪事项的进展,我们还可以实现一个通知功能。系统可以根据事项的截止日期,提供及时的提醒,以确保事项按时完成。 另外,可以实现一个搜索功能,用户可以根据关键词来搜索和过滤事项。这样用户可以更轻松地找到和管理相关的事项。 对于团队合作,可以添加团队成员的功能,每个用户可以查看自己负责的事项。团队成员可以协作工作,共享事项的进展和备注。 为了保证系统的稳定和安全性,可以实现数据备份和权限控制功能。定期备份数据可以防止数据丢失,同时针对不同用户,可以设置不同的权限以确保数据的保密性。 通过编写以上源码,我们可以实现一个功能完善的事项跟进管理系统。用户可以通过该系统更好地管理工作任务,从而提高工作效率和团队合作能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值