http://www.cnblogs.com/beanmoon/archive/2012/11/22/2782442.html

在程序中,集合类每天都在使用,以致于某些代码充斥着List和Map,一直没有机会整理下它们背后的实现原理。这几天不太忙,正好可以看会代码,补充下概念。 
和集合类的大致分类类似,下面我也分List,Map和Set来描述。

一. List 
1).ArrayList

 ArrayList维护着一个对象数组。如果调用new ArrayList()后,它会默认初始一个size=10的数组。 
 每次add操作都要检查数组容量,如果不够,重新设置一个初始容量1.5倍大小的新数组,然后再把每个元素copy过去。 
 在数组中间插入或删除,都要移动后面的所有元素。(使用System.arraycopy())

2).LindedList 
LinkedList的实现是一个双向链表。每个节点除含有元素外,还包含向前,向后的指针。 
新建一个LinkedList,生成一个头节点(header,就是一个头指针),它的元素为null。

它自包含,next和previous指针都指向自己。 
执行add(Object obj)方法后,会生成一个新节点

Header节点的next指向链表的第一个节点,previous指向链表的最后一个节点,在这里都是first。 
再增加一个对象,它的形状像下面这样。

现在是一个标准的双向链表形状。每个节点都有自己的next和previous指针。 
 增加节点,只会对链表的指针进行操作,速度快 
 LinkedList实现了Deque,所以它有双向队列的特征,在链表两端可增删数据 
 使用index查找对象时,会以index和size/2比较,从前或从后向中间搜索 
 ListIterator可向前或向后迭代

比较ArrayList和LinkedList的结构,就可以得出: 
1. ArrayList的remove和add(index, Object)操作代价高,需要移动后面的每个元素。 
2. LinkedList的get(index)操作代价高,它要先循环遍历list,找到Object

二. Map 
1).HashMap 
HashMap的结构是一个散列桶,桶内的每一个键值对(key/value)称为一个元素(entry),当有多个元素时,通过链表链接起来。初始化时生成如下结构

每个bucket是包含一个或多个Entry(map自定义的一种结构,包含一个往后的指针)的链表。 
在put(key, value)后,它的结构如下

将key的hashcode再次散列,然后用这个hash和length-1进行按位与操作,得到bucket的index,然后检查当前bucket的链表,有没有这个key,如果有替换value,没有则跟在链表的最后。 
 允许key和value都可以是null 
 Index=0的bucket存key=null的value,也可以是其它hashcode为0的项 
 初始容量必须为2的幂次(我的理解是,在生成index的时候有这样的代码:hase ^ (length - 1))(注:^为按位异或操作),length – 1的二进制代码为全1,则容易进行hash的设计) 
 如果两个key散列后的index一样的话,第一个key生成的Entry先存在桶中,第二个key生成的Entry会将第一个Entry设为自己的next,串起来。(如图中,先put(yy, “first”),会将这个Entry设为bucket的第一项,后put(xx,”second”),则生成新Entry,它的next为key为yy的Entry,生成一个链表) 
 在put操作中,会比较threshold(capacity * load_factor,一个临界值),如果size > threshold的话,生成一个当前bucket两倍数量的buckets,然后把现有的数据重新散列到新bucket中 
 对HashMap迭代时,返回数据的顺序是:index从0到length-1,循环遍历每个bucket,把不为null的数据取出,每个bucket内的顺序由链表的顺序决定。而不是由插入数据决定。

2).LinkedHashMap 
上面说过,Map的迭代不由插入顺序决定。如果要保持这种顺序呢?就要新增加一种结构来保持。

LinkedHashMap是HashMap的子类,增加一个双向链表,用来存储每个新加入的节点。在遍历时,按链表的顺序进行。其实差不多就是上面HashMap和LinkedList的和吧。

区别:
1、HashMap里面存入的键值对在取出的时候是随机的,是我们最常用的一个Map。它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map 中插入、删除和定位元素,HashMap 是最好的选择。

2、 LinkedHashMap 继承了HashMap,如果需要输出的顺序和插入的相同,那么用LinkedHashMap可以实现;LinkedHashMap还可以通过设置accessOrder为true来实现LRU顺序的输出。

3、TreeMap取出来的是排序后的键值对。但如果要按自然顺序或自定义顺序遍历键,那么TreeMap是一个很好的选择。

三. Set 
1).HashSet 
HashSet使用HashMap来保持元素。Key = 元素,value是一个公有的对象,对每个元素都一样,在HashMap里面key是惟一的,当然很适合于构造set集合。等同于用HashMap包装了次,显示Set自己的特性。

最后还要提到集合类里面一个很重要的类:Collections,它有很多自己独特的静态方法。当然它主要提供几种特殊集合(List, Map,Set),可以调用静态方法来获得:Unmodifiable*(不可修改集合,不可添加或删除元素),Synchronize*(保持同步集合,它的基本每个方法都加锁,防止并发操作),Checked*(声明之始传入特定类型,以后的操作都会验证加入元素是否属于已定类型),Singleton*(集合中只包含一个元素)。它们都是通过包装集合类中的抽象类获得,产生不同的行为。

上面是常见的几种集合类,其它类我很少使用到。

原文链接:http://langyu.iteye.com/blog/360728

 

java主要集合类的数据结构学习的更多相关文章

  1. java主要集合类的数据结构

    1).ArrayList  ArrayList维护着一个对象数组.如果调用new ArrayList()后,它会默认初始一个size=10的数组.  每次add操作都要检查数组容量,如果不够,重新 ...

  2. (4)java数据结构--集合类及其数据结构归纳-有大图

    Java集合类及其数据结构归纳 - s小小的我 - 博客园http://www.cnblogs.com/shidejia/p/6433788.html ---------大图可以 在新标签中打开图片 ...

  3. java集合类源码学习一

    对于java的集合类,首先看张图 这张图大致描绘出了java集合类的总览,两个体系,一个Collection集合体系一个Map集合体系.在说集合类之前,先说说Iterable这个接口,这个接口在jdk ...

  4. 马凯军201771010116《面向对象与程序设计Java》第十一周学习总结

    一.理论知识部分 第九章  集合 1.数据结构介绍:线性结构:线性表,栈,队列,串,数组,文件.非线性结构:树,图. 散列表:又称为哈希表. 散列表算法的基本思想是:以结点的关键字为自变量,通过一定的 ...

  5. 201771010126 王燕《面向对象程序设计(java)》第二周学习总结

    201771010126 王燕<面向对象程序设计(java)>第二周学习总结 一.理论知识学习部分 3.1j简单 的java应用程序 标识符由字母.下划线.美元符号和数字组成, 且第一个符 ...

  6. 王之泰201771010131《面向对象程序设计(java)》第四周学习总结

    王之泰201771010131<面向对象程序设计(java)>第四周学习总结 第一部分:理论知识学习部分 第四章 1.类与对象的基础概念. a.类(class)是构造对象的模板或蓝图.由类 ...

  7. 王之泰201771010131《面向对象程序设计(java)》第二周学习总结

    王之泰201771010131<面向对象程序设计(java)>第二周学习总结 第一部分:理论知识学习部分 第三章 第三章内容主要为Java语言的基础语法,主要内容如下 1.基础知识 1.1 ...

  8. 李清华201772020113《面向对象程序设计(java)》第二周学习总结

    李清华201772020113<面向对象程序设计(java)>第二周学习总结 第一部分 理论知识 第三章 本章主要讲了java基本知识中的标识符,关键字,注释,以及数据类型,变量,运算符, ...

  9. 20172325 2018-2019-2 《Java程序设计》第九周学习总结

    20172325 2018-2019-2 <Java程序设计>第九周学习总结 教材学习内容总结 图的定义 图是由顶点集(VertexSet)和边集(EdgeSet)组成,针对图G,顶点集和 ...

随机推荐

  1. 2018. 2.4 Java中集合嵌套集合的练习

    创建学生类有姓名学校和年龄 覆盖toString() 1.创建三个学生对象,放到集合ArrayList 2.输出第2名学生的信息 3.删除第1个学生对象 4.在第2个位置插入1个新学生信息 5.判断刘 ...

  2. 第四章 用javascript和DOM去建立一个图片库

    把整个图片库的浏览链接集中安排在你的图片库里,只在用户点击了这个主页里的某个图片链接时才把相应的图片传送给它. 代码如下: <body> <ul> <li> < ...

  3. php 单例模式笔记

    <?php /** * 单例模式1. 它们必须拥有一个构造函数,并且必须被标记为private2. 它们拥有一个保存类的实例的静态成员变量3. 它们拥有一个访问这个实例的公共的静态方法单例类不能 ...

  4. 小弟在研究CUDA时出现一个问题,求解

    这是<GPU高性能编程CUDA中文实战>中的例子,第七章,热传导模拟,但是出现下面的问题,求牛人解读.小弟跪谢... 主要问题就是关键字变白. 但是添加需要的头文件后一些系统自带的关键字也 ...

  5. 在DOS界面下快速进入目录的技巧

    在DOS界面如果想进入某一目录还是比较困难的,尤其是有长目录名和中文目录名的时候. 比如:要进入“D:/工具箱/杀毒软件”这个目录. 1.在Windows下进入这个目录. 2.在地址栏输入 C:/WI ...

  6. jQuery Pagination分页插件--刷新

    源码地址:https://github.com/SeaLee02/FunctionModule/blob/master/UploadFiles/WebDemo/FenYE/FenYeDemo.aspx ...

  7. SQL SERVER 2012数据库自动备份的方法

    SQL SERVER 2012数据库自动备份的方法 为了防止数据丢失,这里给大家介绍SQL SERVER2012数据自动备份的方法: 一.打开SQL SERVER 2012,如图所示: 服务器类型:数 ...

  8. 03_14_final关键字

    03_14_final关键字 1. Final关键字 final的变量的值不能够被改变 final的成员变量 final的局部变量(形参) final的方法不能够被重写 final的类不能够被继承

  9. 【计数】cf938E. Max History

    发现有一种奇怪的方法不能快速预处理? 复习一下常见的凑组合数的套路 You are given an array a of length n. We define fa the following w ...

  10. vim正则表达式的替换变量

    在正规表达式中使用 \( 和 \) 符号括起正规表达式,即可在后面使用\1.\2 等变量来访问 \( 和 \) 中的内容. 例如有下列英汉对照文本: adapter 适配器address 地址alge ...