第十章 更丰富的存储——Java集合框架
掌握:
- List接口及其实现类ArrayList 和LinkedList的特点和使用场合。
- List集合如何排序。
- Set 接口及其HashSet 和TreeSet的特点和使用场合。
- 理解引用相等性和对象相等性。
- Map接口的特点及其HashMap和TreeMap的特点和使用场合。
- 理解泛型。
一、概念引入
有时我们会使用对象数组进行存储,然而数组都是定长的,有时事先并不知道程序运行时会需要多少对象,这就需要一个可变长的容器:Java集合框架。
Java集合框架为我们提供了一套性能优良、使用方便的接口和类,它们位于java.util包中。它支持绝大多数用到的数据结构,有了它,我们不必再重新发明轮子,只需要学会如何使用它们,就可以处理实际应用中的问题了。
Java集合框架主要提供了如下几种接口和实现类:
(1)单值操作接口:Collection、List、Set
(2)键值对操作接口:Map
(3)输出接口:Iterator、Listlterator
(4)比较接口:Comparable、Comparator
(5)List接口实现类:ArrayList和LinkedList
(6)Set接口实现类:HashSet和TreeSet
(7)辅助工具类:Collections类和Arrays类
二、List接口及其实现类
1、List接口
List接口主要有两个特点:
(1)有序的,这里的有序并不是排好了序,而是指元素放进去的顺序和取出来的顺序是一样的。
(2)可重复的,允许有相同的元素存在。
2、List接口的两个实现类
- 可变数组——ArrayList
ArrayList底层使用数组作为实现结构,但是元素个数不受限制,是大小可变的数组,在内存中分配连续的空间,遍历元素和随机访问元素的效率比较高,不足之处是任何不在结尾处增加元素或删除元素的操作都会引起大量元素的移位,这种情况下效率不高。
- 链表——LinkedListLinkedList
底层采用链式存储结构,插入、删除元素时不会引起大量元素的移动,效率高。它专门提供了对尾部和头部添加和删除的操作方法,而且效率很高。
3、List集合排序
使用 Collection类的 sort()方法注意:使用Collection类时,需要继承Comparable接口,并重写它的compareTo方法
三、Set接口及其实现类
1、Set接口
Set 接口与List接口相比,其结构特点如下:
(1)无序的,即放进去的顺序与出来的顺序不同。
(2)不可重复的,注重独一无二的性质。
2、两个实现类之HashSet
- HashSet是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。
- TreeSet则是以二叉树的方式来存储元素,它可以实现对集合中的元素进行排序。
如何确保没有重复元素?
HashSet所存储的元素是不可重复的,并且元素都是无序的。当HashSet集合中添加一个对象时,首先会调用该对象的HashSet()方法来计算对象的哈希值,从而确定元素的存储位置,如果此时哈希值相同,再调用对象的equals()方法来确保该位置没有重复元素。
3、引用相等性和对象相等性
(1)引用相等性
引用堆上同一个对象的两个引用是相等的。此时调用HashCode(),结果相同。
判断两个引用是否相等,可以使用==来比较变量上的字节组合。
引用到相同的对象,字节组合也会一样。
(2)对象相等性
对象本身是相等的也就是说 堆上的两个对象在意义上是相同的。
小结:引用相等性时,HashSet认为是重复的元素,但是对象相等性HashSet并不认为是重复的。
如何让Set添加不进去对象本身是相等的对象呢?
(1)覆盖从Object继承来的hashCode()方法。hashCode()方法主要是用来 缩小寻找的成本,但hashCode相同并不一定能够保证对象本身是相等的,因为hashCode()方法所使用的杂凑算法可能凑巧是的多个对象传回相同的hashCode,越糟糕的算法,碰撞的几率越大。
(2)在hashCode相同的前提下,还要通过重写equals()方法来认定是否真正找到了相同的对象。
4、Set集合如何排序?
TreeSet是Set接口另外一个实现类,它和HashSet很相似,也是不可重复的,但是有一点不同,它会一直保持集合处于有序的 状态。
使用TreeSet必须知道的事情:
集合中的元素必须是实现Comparable接口的类型或使用带Comparator参数的构造方法来创建TreeSet。
Java中Comparable类的compareTo()方法的返回值当两个对象进行比较时,返回0代表它们相等;返回值<0(如-1)代表this排在被比较对象之前;反之代表在被比较对象之后
四、Map接口及其实现类
Collection接口、List接口、Set接口及其实现类一次只能存储一个值,是单值集合,而在某些情境下我们需要保存一对值,以key->value的形式保存。
如果要存放键值对,可以使用Map接口及其实现类。
1、Map接口主要的特点是:
(1)键(key)不允许重复
(2)一个键(key)只能映射到一个值(value)
2、两个实现类
Map接口有三个常用的实现类HashMap、Hashtable、TreeMap
由于Hashtable较为过时,我们重点分析HashMap 和 TreeMap
(1)HashMap底层的实现利用了哈希表结构,因而集合中的元素仍然不会按次序排列。
HashMap主要的方法:
No | 方法 |
---|---|
1 | V put (K key,V value) |
2 | V get (Object key) |
2 | V remove (Object key) |
4 | boolean containsKey (Object key) |
5 | boolean containsValue (Object value) |
6 | Set < K > keySet ( ) |
7 | Collection < V > values ( ) |
8 | Set< Map , Entry< K,V >> entrySet ( ) |
9 | int hashCode ( ) |
10 | Boolean equals (Object o) |
11 | void clear ( ) |
(2)TreeMap底层采用红黑树结构,而HashMap使用哈希表结构。
TreeMap中的元素按key自动排序,而HashMap是无序的。