Java集合API
苦不堪言~~
Java Collection Framework API
集合,也叫容器类。 它的功能,就相当于容器。
Java的集合(容器),它是用来“装对象的”。
容器,应该有哪些方法供你使用?
- 把东西丢进容器中
- 把指定的东西“读取”出来,该东西依然在容器里。
- 把指定的“东西”从容器中删除。
- “挨个”把每个东西数一次。(遍历)
- 把容器“倒空”。
- 把A容器中东西,全部倒入B容器中。
集合 + 集合
- 拿A容器包含的东西,减去B容器中包含的东西。
集合 - 集合
- 拿A容器包含的东西,与B容器中包含的东西 求交集。
集合 ∩ 集合
遍历Set集合,有两种方式:
A。 用迭代器。
B。 用foreach循环。
底层用一个数组存元素——而且这个数组的长度永远是2的N次方。
HashSet的构造器:HashSet(int initialCapacity ,
float loadFactor)
- initialCapacity: 控制底层数组的长度。默认为16
如果传入数组长度不是2的N次方,HashSet会自动将它扩展到2个N次方。
- loadFactor: 当HashSet【感觉到底层数组快满】的时候,再次创建一个长度为
原有数组长度2倍的数组。原有的数组就变成垃圾——并且要把原有数组的元素复制到新数组中。 专业说法叫“rehash(重hash)”.
当loadFactor为0.75时,75%的桶已满时,HashSet会分配新的数组。
当loadFactor为0.1时,10%的桶已满时,HashSet会分配新的数组。
当loadFactor为1时,100%的桶已满时,HashSet会分配新的数组。
loadFactor越小,越耗内存;loadFactor越大,性能越低。
—— loadFactor越大,代表当数组很满时,才去“重hash”,
数组越满,就越有可能出现链表。
HashSet存入的机制:
(1)当添加元素时,HashSet会调用该对象的hashCode()方法,得到一个int值。
(2)根据hashCode()返回的int值,计算出它在【底层数组】的存储位置(数组中索引)。
(3)如果要加入的位置是空的,直接放入即可。
(4)如果要加入的位置已经有元素,此处就会形成“链表”。
HashSet取元素的机制:
(1)当要取一个元素时,HashSet会调用该对象的hashCode()方法,得到一个int值。
(2)根据hashCode()返回的int值,计算出它在【底层数组】的存储位置(数组中索引)
(3)如果该位置恰好是要找到元素,直接取出即可。
(4)如果该位置有链表, HashSet要“挨个”搜索链表里的元素。
最理想的情况下,HashSet的性能几乎可以数组匹敌,存、取的性能非常高。
HashSet怎么才会认为两个对象是相等的?
A。 两个对象的hashCode()返回值相等。
B。 两个对象通过equals比较也返回true。
——这就要求我们自定义类的hashCode()与equals()方法是一致的。
要求程序重写equals()所用的关键属性,与计算hashCode()所用的关键属性要相同。
它与HashSet的存储机制相似。
LinkedHashSet额外地维护一个链表,这个链表可以保证LinkedHashSet能记住元素添加顺序。
特征:保证Set里的元素是“大小排序”的。
TreeSet
——
它是标准的“红黑树”。
●
树 → 二叉树 → 排序二叉树 → 平衡的排序二叉树 → 红黑树。
TreeSet的存入、检索机制:
底层用一棵“ 红黑树”存放所有数据。
元素存入、检索的性能也比较好。
在HashSet没有大量出现“链表”的情况下,HashSet性能比TreeSet性能好。
如果HashSet经常发生“重Hash”
A。 TreeSet不会像HashSet有“空桶”
B。 TreeSet可以保证集合元素是按“大小”排序的。
使用TreeSet有一个要求:
要求集合元素必须是可以比较大小。
Java的比较大小有两种方式:
A - 自然排序。 所有集合元素实现Comparable接口。
集合元素实现了Comparable接口后,集合元素自身就是可排序的。
B - 定制排序。 要求创建TreeSet时,提供一个Comparator对象。
Comparator对象可负责对元素进行比较大小。
集合元素无需实现Comparable接口,因此集合元素本身是无法排序的。
TreeSet怎么才会认为两个对象是相等的?
A。 只要两个对象通过compareTo比较返回0, TreeSet认为它们是相等的。
它提供了大量的“根据索引”来存、取元素的方法。
由于List可以“根据索引”来存、取元素的方法。
所以它多一个遍历集合元素的方法。
ArrayList与Vector的存储机制:
它们底层完全基于数组——它对元素的存储,完全是基于数组的,
因此性能非常快。
ArrayList与Vector的区别:Vector是一个JDK1.0就有的集合,
从JDK 1.2之后,Sun重写设计了ArrayList,代替了原来的Vector。
ArrayList是线程不安全的;Vector是线程安全的。
——ArrayList的性能比Vector要好。
即使在多线程环境下,可以使用Collections把ArrayList保证成线程安全的。
LinkedList
既是线性表,又是队列,还是栈。
LinkedList底层是基于链表实现的。通常认为它的性能比上ArrayList。
ArrayList: 由于可以根据底层数组的索引存、取元素,所以性能非常快。
当插入元素、 删除元素, 后面的所有元素要跟着“整体搬家”。
LinkedList:由于底层采用了链表来存储元素,因此根据索引存、取元素,所以性能较慢。
当插入元素、 删除元素,无需“整体搬家”,所以性能非常快。
—— 它是功能被限制了的线性表。
既是队列 , 又是栈。
ArrayDeque - 基于数组实现。
LinkedList - 基于链表实现。
Arrays
- 操作数组。
Objects
- 操作对象。
Collections - 操作集合。
synchronizedXxx - 把原有的集合,包装成线程安全的集合。
Set集合,就是Collection。它们的行为完全相似。
HashSet的存储机制:
![微笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/smile.gif)
![微笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/smile.gif)
HashSet还有一个子类:LinkedHashSet。
TreeSet
List集合
Deque集合
操作集合的工具类: Collections