Java数组的长度是固定的,为了使程序能够方便地存储和操作数目不固定的一组数据,JDK类库提供了Java集合,这些集合类都位于java.util包中,但是与数组不同的是,集合中不能存放基本类型数据,而只能存放对象的引用。
Java集合主要分为以下三种类型:
Set(集):集合中的对象不按特定方式排序,且没有重复对象。它的有些实现类能对集合中的对象按照特地方式排序。
List(列表):集合中的对象按照索引位置排序,可以有重复对象,允许使用索引检索对象。
Map(映射):集合中的每一个元素都包含一对键对象和值对象(key-value),集合中的键对象是不能重复的,它的一些实现类能对集合中的键对象进行排序。
java主要集合类的类框图
(Interface与Interface之间为继承关系,是实线箭头,图中有误)。
Collection接口和Iterator接口
在Collection接口中声明了适用于Set和List的通用方法:
方法 | 描述 |
boolean add(Object o) | 向集合中加入一个对象的引用 |
void clear() | 删除集合内的所有对象,即不再持有这些对象的引用 |
boolean contains(Object o) | 判断在集合中是否持有这些对象的引用 |
boolean isEmpty() | 判断集合是否为空 |
Iterator iterator() | 返回一个Iterator 对象,可用它来遍历集合中的元素 |
boolean remove(Object o) | 从集合中删除一个对象的引用 |
int size() | 返回集合中元素的数目 |
Object[] toArray() | 返回一个数组,该数组包含集合中的所有元素 |
Iterator iterator()方法返回一个Iterator对象,Iterator对象采用了快速失败机制,例如,当通过Collection对象的iterator()方法得到一个Iterator对象后,紧接着利用ction集合的一些方法对集合进行了修改操作,则接下来访问Iterator对象的next()方法会抛出ConcurrentModificationException运行时异常。
Iterator接口提供了遍历各种类型集合的统一接口。Iterator接口声明了如下方法:
方法 | 描述 |
hasNext() | 判断集合中的元素是否遍历完毕,如果没有,则返回true |
next() | 返回下一个元素 |
remove() | 从集合中删除上一个由next()方法返回的元素 |
Set(集)
Set是最简单的一种集合,集合中对象不按特定方式排序(没有索引),并且没有重复对象。Set主要有两个实现类:HashSet和TreeSet。HashSet类按照哈希算法来存取集合中的对象,当向集合中加入这个对象时,HahshSet会调用对象的hashCode()方法来获得哈希码,然后根据哈希码进一步计算出对象在集合中存放的位置,因此存取速度比较快。HashSet类还有一个子类LinkedHashSet类,它不仅实现了哈希算法,而且还实现了链表数据结构。链表数据结构能够提高插入和删除元素的性能。TreeSet类实现了SortSet接口,具有排序功能。
Set集合中存放的是对象的引用,且没有重复对象。下面这个例子:
以上程序的打印结果为2.因此Set集合的add()方法是以用equals方法来判断对象是否已经存在与集合之中的。equals与“==”的区别自行google。
TreeSet类实现了SortSet接口,具有排序功能。下面这个例子:
以上程序打印的结果为 1 2 3 4 。因此当向TreeSet集合中插入对象时,会把他插入到有序的对象序列中。TreeSet支持两种排序方式:自然排序和客户化排序。在默认情况下采用自然排序方式。
1、自然排序
JDk类库中已经实现了Comparable接口的一些类的排序方式如下表:
类 | 排序 |
Byte 、Double 、Float 、Interger 、Long 、Short | 按数字大小排序 |
Character | 按字符的Unicode值的数字大小排序 |
String | 按字符串中字符的Unicode值排序 |
2、客户化排序
我们可以通过实现Comparator<Type>接口来自定义排序方式,其中Type为指定被比较对象的类型。Comparator接口中有个compare(Type x,Type y)方法,用于比较两个对象的大小,当返回值大于0.表示x大于y,反之亦然。下面这个例子:
首先要实现Comparator接口
然后就可以自动进行客户化排序了:
以上程序打印的结果如下:
List(列表)
List列表的主要特征是其元素以线性方式存储,集合中允许存放重复对象。List接口的主要实现类包括:
1、ArrayList:代表长度可变的数组。允许对元素进行快速的随机访问(即检索位于特定索引位置的元素),但是向ArrayList中插入与删除元素较慢。
2、LinkedList:在实现中采用了链表数据结构,对顺序访问进行了优化,向其中插入与删除元素较快,随机访问速度则较慢。LinkList单据具有addFirst()、addLast()、getFirst()、getLast()、removeFirst()、rmoveLast()方法。
我们可以通过get(int index)方法获取指定索引位置的对象。也可以通过获得Iterator对象对其进行遍历。
List只能对集合中的对象按照索引位置进行排序,如果希望按其他方式排序,可以借助Comparator接口和Collection类。Collection类是Java集合类库中的辅助类,它提供了操纵集合的各种静态方法,其中sort()方法用于对List中的对象进行排序:
1、sort(List list) :对List中对象进行自然排序。
2、sort(List list,Comparator comparator) :对List中对象进行客户化排序。
ListIterator接口
List的listIterator()方法返回的是ListIterator对象。ListIterator接口继承自Iterator接口,此外还专门提供了专门操纵列表的方法:
方法 | 描述 |
add() | 向列表中插入一个元素 |
hasNext() | 判断集合中的元素是否遍历完毕,如果没有,则返回true |
hasPrevious() | 判断集合中的元素是否有上一个元素,如果没有,则返回true |
next() | 返回下一个元素 |
previous() | 返回上一个元素 |
比较Java数组和各种List的性能
通过测试得到的操作时间:
类型 | Java数组 | ArrayList | LinkedList |
随机访问操作(get) | 16 | 23 | 63 |
迭代操作(iterate) | 31 | 47 | 33 |
插入操作(insert) | 不适用 | 1610 | 31 |
删除操作(remove) | 不适用 | 6625 | 16 |
从表中可以看出,对Java数组的随机访问和迭代具有最快的访问速度;对LinkedList的插入和删除操作具有最快的速度,对ArrayList的随机访问也具有较快的访问速度。
Map(映射)
Map(映射)是一种键对象和值对象进行映射的集合。利用put(Object key ,Object value)向Map集合中加入元素,因此必须提供一对键对象和值对象。利用get(Object key)从Map集合中检索元素,因此只要给出键对象,就会返回对应的值对象。
Map集合中的键对象不允许重复,重复后后一个值对象将会覆盖前一个的值对象。
Map.Entry表示Map中的一对键和值。Map的entrySet()方法返回一个Set集合,这个集合中存放了Map.Entry类型的元素。
Map有两种比较常用的实现:HashMap和TreeMap,HashMap有较好的存取性能。TreeMap实现了SortedMap接口,能对键对象进行排序,同样提供了自然排序和客户化排序两种方式。
新的遍历集合的方法:
除了用Iterator来遍历集合外,还可以用以下代码遍历集合:
集合实用类:Collections
该类提供了一系列操纵List类型集合的静态方法。
主要笔记来自《Java面向对象编程》