Java集合

一、Set和Map
Set代表一种集合元素无序、集合元素不可重复的集合,Map代表一种由多个key-value对组成的集合,可以这么说,Map集合是Set集合的拓展。
Map和Set的关系:Map集合的Key具有一个特征:所有key不能重复,并且没有顺序,也就是说,如果将Map集合中的所有Key集中起来,那这些key就组成了一个set集合。对于map而言,相当于每个元素都是key-value的Set集合。

1、HashMap和HashSet
HashSet:系统采用Hash算法决定集合元素的存储位置,这样可以保证快速存取集合元素。
HashMap:系统将Value作为key的附属,系统根据Hash算法来决定key的存储位置,这样可以保证快速存取集合Key,而value总是跟随key存储。
note:集合存放的只是对象的引用。

HashMap put步骤:
1,根据key的keyCode计算Hash值
2,搜索指定hash值在对应table中的索引
3,如果i处索引处的Entry不为null,通过循环不断遍历e元素的下一个元素
4,找到指定key与需要放入的key相等,新添加Entry的value将覆盖原有Entry的value,但key不会覆盖
5,如果i索引处的Entry为null,表明此处还没有Entry
6,将key,value添加到i索引处
note:当系统决定存储HashMap中的key-value对时,完全没有考虑Entry中的value,而仅仅只是根据key来计算并决定每个Entry的存储位置,在key的hash如果通过equals比较两个Entry的key发现相等,就会替换掉原有entry中value值,如果不相等,新添加的Entry将与原有Entry形成Entry链。addEntry()方法。

HashMap构造器,默认初始容量为16,如果需要指定初始容量,最好指定为2的n次方。
当HashMap的每个bucket里存储的Entry只是单个Entry,即没有通过指针产生Entry链时,此时的HashMap具有最好的性能。

负载因子:默认为0.75,增大负载因子可以减小Hash表(实际上就是Entry数组)所占用的内存空间,但会增加查询数据的时间开销,减小负载因子会提高数据查询的性能,但会增加Hash表所占用的内存空间。

HashSet是基于HashMap实现的,底层仍然采用HashMap来保存所有的元素。封装了一个HashMap对象来存储所有的集合元素。所有放入HashSet中的集合元素实际上由HashMap的key来保存,而HashMap的value则存储了一个静态的Object对象。因此HashSet和HashMap在实现本质上是相同的。

当试图把某个类的对象当成HashMap的key,或者试图将这个类的对象放入HashSet中保存时,重写equals方法和hashCode方法很重要,而且这两个方法的返回值必需保持一致。

2、TreeMap和TreeSet
HashSet底层依赖于HashMap实现,TreeSet底层则采用一个NavigableMap来保存TreeSet集合的元素,由于NavigableMap只是一个接口,因此底层仍然采用TreeMap来保存Set集合中的所有元素。
TreeMap,底层采用红黑树的排序二叉树来保存Map中的每个Entry,每个Entry都被当成红黑树的一个节点来看待。

TreeMap添加元素、取出元素的性能都比HashMap低,这些操作都需要通过循环找到新增Entry的插入位置,因此比较好性能,优势在于:TreeMap中所有的Entry总是按key根据指定排序规则保存有序状态,TreeSet中所有元素总是根据指定排序规则保持有序状态。

二、Map和List
Map接口提供了get(Key)方法允许对象根据key获取value.
List接口提供了get(int index)方法允许List对象根据元素索引来取得value.

List相当于所有key都是int类型的Map,也可以说Map相当于索引是任意类型的List.

ArrayList和LinkedList
List三个主要实现类:ArrayList、Vector、LinkedList
Vector还有一个Stack子类,仅在Vector的基础上增加了5个方法,Stack和Vector都是线程安全的类。
在无需保证线程安全的情况下,推荐使用ArrayDeque来代替Stack类。
Deque代表双端队列这种数据结构,他既有队列的先进先出性质,也具有栈的性质,既是队列,也是栈。
ArrayList和ArrayDeque底层都是基于数组实现的,只是所提供的方法不同。

Vector和ArrayList的区别
1,Vector和ArrayList都继承自List,底层都是基于数组,但是ArrayList使用transient修饰底层数组,保证序列化ArrayList对象的时候不会直接序列化底层数组,而是通过writeObject和readObject来实现定制序列化,Vector没有实现。
因此ArrayList比Vector的序列化实现更安全。
2,Vector是线程安全的,ArrayList不是。
3,数组扩充:
ArrayList:int newCapacity = (oldCapacity3)/2+1 //将新容量扩充为原来的1.5倍
Vector:int newCapacity = (capacityIncrement>0)?(oldCapacity+capacityIncrement):(oldCapacity
2); //如果capacityIncrement>0,新容量 = oldCapacity+capacityIncrement,否则扩充为原来的两倍。

ArrayList和LinkedList的实现差异
1,List代表一种线性表的数据结构,ArrayList则是一种顺序存储的线性表。
2,ArrayList底层采用数组来存储每个集合元素。LinkedList是一种链式存储的线性表。其本质上是一个双向链表,不仅实现了List接口,还实现了Deque接口。也就是说LinkedList不仅可以当成双向链表使用,还可以当成栈来使用,还可以当成队列来使用。
3,ArrayList添加、删除集合元素时,ArrayList底层都需要对数组进行“整体搬家”,性能非常差。

ArrayList和LinkedList的性能分析和使用场景
1,当程序需要以get(int index)方法获取指定索引处的元素时,ArrayList>LinkedList,
2,当程序调用add(int index,Object obj)向List集合添加元素时,ArrayList需要对底层数组元素进行整体搬家,如果添加元素导致集合长度将要超过底层数组长度,ArrayList必须新建一个长度为原来长度1.5倍的数组,再有垃圾回收机制回收原有数组,系统开销较大。对于LinkedList而言,他的开销主要集中在根据index找到元素的过程,即使如此:LinkedList>ArrayList
3,当程序调用remove(int index)方法删除index处的元素时,ArrayList同样需要对底层数组元素进行整体搬家,但是无需考虑创建新的数组,因此:LinkedList约等于ArrayList
4,当程序调用add(Object obj)时,大多数时候无需对数组进行整体搬家,但是如果添加元素导致集合大小大于数组大小,ArrayList必须新建一个长度为原来长度1.5倍的数组,这样开销就比较大了,LinkedList则有比较好的性能。因此:LinkedList>ArrayList

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容