Collection体系的常用类

常用类包括但不限于:

  • List
  • Set
  • Map

List

最常用的就是ArrayList,其本质上就是一个数组

ArrayList是如何扩容的?

通过grow函数,创建size右移一位的数组,再addAll一遍

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

Set

本质利用equals方法,不允许重复元素的集合

Set的add是比较低效的

因为每次set都要遍历一遍,挨个equals过去,o(n)的复杂度

HashSet

最常⽤,最⾼效的Set实现

  • 使⽤HashSet对ArrayList去重
  • HashSet是⽆序的, 如果有需要可以使⽤LinkedHashSet

hashCode:Java世界⾥第⼆重要的约定
同⼀个对象必须始终返回相同的hashCode

在HashSet中,利用hash桶,将同样的hashcode的value塞到同一个桶里,如此往复,判断equals的时候,就可以通过判断hashcode到对应的hash桶里遍历,o(log2n)的复杂度

约定:

  • 同⼀个对象必须始终返回相同的hashCode
  • 两个对象的equals返回true,必须返回相同的hashCode
  • 两个对象不等,也可能返回相同的hashCode

哈希冲突: 大量的key的hashcode都一样,导致全部分配到了一个hash桶里,这样将导致hashset的高效性大大降低,成为了一个set

Map

一种key,value形式的数据结构, 一个map不能包含重复的key。用来取代Dictionary类的存在

常用方法:

  • C/U: put()/putAll()
  • R: get()/size()/containsKey()/containsValue()/keySet()/values()/entrySet()
  • D: remove()/clear()

HashMap

HashMap的扩容

HashMap的keySet本质上也是一个HashSet,他利用了hash桶的高效性。
但是因为哈希冲突无法完全避免,因此为了提高HashMap的性能,HashMap不得尽量缓解哈希冲突以缩短每个桶的外挂链表长度。

所以当存储Entry较多的时候,就需要考虑增加hash桶的数量,也就涉及到了扩容

public HashMap(int initialCapacity, float loadFactor) ;
  • 第一个参数:初始容量,指明初始的桶的个数;相当于桶数组的大小。
    第二个参数:装载因子,是一个0-1之间的系数,根据它来确定需要扩容- 的阈值,默认值是0.75。
  put() {
    ...
    if (++size > threshold)  resize();
  }
  // HashMap在Put的时候会判断size,然后动态扩容
  
  if (oldCap > 0) {
    if (oldCap >= MAXIMUM_CAPACITY) {
      threshold = Integer.MAX_VALUE;
      return oldTab;
    }
    else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
      oldCap >= DEFAULT_INITIAL_CAPACITY)
      newThr = oldThr << 1; // double threshold
    }

HashMap在Put的时候会判断size, 始终保持 2^n,扩容后数组大小为当前的 2 倍

扩容的数组的长度为什么保持 2^n?
其实这是为了保证通过hash方式获取下标的时候分布均匀。数组长度为2的n次幂的时候,不同的key 算得得 index 相同的几率较小,那么数据在数组上分布就比较均匀,也就是说碰撞的几率小,相对的,查询的时候就不用遍历某个位置上的链表,这样查询效率也就较高了。

HashMap的线程不安全性

HashMap和HashSet本质上是⼀种东⻄

  * Returns a {@link Set} view of the keys contained in this map.
  * The set is backed by the map, so changes to the map are
  * reflected in the set, and vice-versa. 
  // HashMap的keySet是一个HashSet,对hashSet的改变会反馈到map,反之亦然
 

HashMap在Java 7+后的改变:链表->红⿊树

HashMap的存储方式:数组 + 链表 + 红黑树

indexFor: hash & (length -1)

先利用indexFor来给每一个put的数据分到对应的数组下标

数组下标对应的链表,但链表数据膨胀依然会导致查询效率下降

链表大于8个数据会转化为红黑树

转换为红黑树后,利用hash(key)的大小,根据红黑树的特性,可将时间复杂度从链表的o(n)转化为 o(log2n)

扩展

有序集合TreeSet/TreeMap

使用红黑树存储的数据结构,使⽤Comparable约定,认为排序相等的元素相等

Collections⼯具⽅法集合

  • emptySet(): 等返回⼀个⽅便的空集合
  • synchronizedCollection: 将⼀个集合变成线程安全的
  • unmodifiableCollection: 将⼀个集合变成不可变的(也可以
    使⽤Guava的Immutable)

Collection的其他实现

  • Queue/Deque
  • Vector/Stack (replaced by Deque)
  • LinkedList
  • ConcurrentHashMap
  • PriorityQueue

Guava

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