资源描述:
《关于java集合的小抄-java开发java经验技巧》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、关于Java集合的小抄-编程开发技术关于Java集合的小抄原文出处:花钱的年华的博客在尽可能短的篇幅里,将所冇集合与并发集合的特征,实现方式,性能捋一遍。适合所有”精通Java"其实还不那么口信的人阅读。不断更新屮,请尽量访问博客原文。ListArrayList以数组实现。节约空间,但数组有容量限制。超出限制时会增加50%容量,用System,arraycopy()复制到新的数组,因此最好能给出数组大小的预估值。默认第一次插入元素时创建大小为10的数组。按数组下标访问元素-get(i)/set(i,e)的性能很高,这是数组的基木优势。直接在
2、数组末尾加入元索-add(e)的性能也高,但如果按下标插入、删除元索-add(i,c),remove(i),remove(c),则要用System,arraycopy()来移动部分受影响的元素,性能就变差了,这是基本劣势。LinkedList以双向链表实现。链表无容量限制,但双向链表木身使用了更多空间,也需要额外的链表指针操作。按卜•标访问元素-gct(i)/sct(i,c)要悲剧的遍历链表将指针移动到位(如果i>数组大小的一半,会从末尾移起)。插入、删除元素时修改前后节点的指针即可,但还是要遍力部分链表的指针才能移动到下标所指的位置,只有
3、在链表两头的操作-add(),addFirst(),removeLast()或用iterator()上的remove()能省掉指针的移动。CopyOnWriteArrayList并发优化的ArrayListo用CopyOnWrite策略,在修改时先复制一个快照来修改,改完再让内部指针指向新数组。因为对快照的修改对读操作来说不可见,所以只有写锁没有读锁,加上复制的昂贵成本,典型的适合读多写少的场景。如果更新频率较高,或数组较大时,还是Collections.synchronizedList(list),对所冇操作用同一把锁来保证线程安全更好。
4、增加了addlfAbsenl(e)方法,会遍历数组来检查元索是否已存在,性能可想像的不会太好。补充无论哪种实现,按值返回卜标-contains(e),indexOf(e),remove(e)都需遍历所有元素进行比较,性能可想像的不会太好。没有按元素值排序的SortedList,在线程安全类中也没有无锁算法的ConcurrentLinkedList,凑合着用Set与Queue中的等价类时,会缺少一些List特:有的方法。MapHashMap以Entry[]数组实现的哈希桶数组,用Key的哈希值取模桶数组的人小可得到数组下标。插入元素时,如果两
5、条Key落在同一个桶(比如哈希值1和17取模16后都展于第一个哈希桶),Entry用一个next屈性实现多个Entry以单向链表存放,后入桶的Entry将next指向桶当前的Entry。查找哈希值为17的keyII寸,先定位到第一个哈希桶,然后以链表遍历桶里所有元索,逐个比较具key值。当Entry数量达到桶数量的75%时(很多文章说使用的桶数量达到了75%,但看代码不是),会成倍扩容桶数组,并重新分配所有原来的Entry,所以这里也最好有个预估值。取模用位运算(hash&(arrayLength-1))会比较快,所以数组的大小永远是2的N
6、次方,你随便给一个初始值比如17会转为32O默认第一次放入元索时的初始值是16oiteratorO时顺着哈希桶数组来遍丿力,看起来是个乱序。在JDK8里,新增默认为8的閥值,当一个桶里的Entry超过閥值,就不以单向链表而以红黑树来存放以加快Key的查找速度。LinkedHashMap扩展HashMap增加双向链表的实现,号称是最占内存的数据结构。支持iterator()时按Entry的插入顺序来排序(但是更新不算,如果设置accessOrder属性为true,则所有读写访问都算)。实现上是在Entry上再増加属性before/after指
7、针,插入时把自己加到HeaderEntry的前而去。如果所有读写访问都要排序,还要把前后Entry的before/after拼接起来以在链表屮删除掉自己。TreeMap以红黑树实现,篇幅所限详见入门教程。支持iterator()吋按Key值排序,可按实现了Comparable接口的Key的升序排序,或由传入的Comparator控制。可想象的,在树上插入/删除元素的代价一定比HashMap的大。支持SortedMap接口,如firstKey(),lastKey()取得最大最小的key,或sub(fromKey,toKey),ta订Map(f
8、romKey)剪取Map的某一段。ConcurrentHashMap并发优化的HashMap,默认16把写锁(可以设置更多),有效分散了阻塞的概率,而且没有读锁。数据结构为Seg