JavaSE-集合
- Exception概念及使用
- Error
- 运行时异常、编译异常
- 完成Collection理解
- 完成Iterator理解及应用
- 完成List理解及应用
- 完成Set理解及应用
- 完成Collections工具类使用
三、本章目标
- 掌握Collection使用
- 掌握Iterator使用
- 掌握List使用
- 掌握ArrayList、Vector使用
- 掌握LinkedList使用
- 掌握HashSet、TreeSet使用
- 掌握Collections工具类使用
- 知识点
一. 集合概述
介绍
Java集合是使程序能够存储和操纵元素不固定的一组数据。 所有Java集合类都位于java.util包中。
【问】:之前我们需要把多个元素放到一起的时候,使用的是数组。那么为何还要提供Java集合工具类呢?
我们通过对比数组和Java集合工具类来解释Java集合工具类的必要性。
数组 | 集合 |
长度固定 | 长度不固定 |
存放任意类型 | 不能存放基本数据类型,只能存放对象的引用 |
注意:如果集合中存放基本类型,一定要将其 “装箱”成对应的”基本类型包装类”。
二. 层次结构
Java的集合类主要由两个接口派生而出:Collection和Map。Collection和Map是Java结合框架的根接口,这两个接口又包含了一些子接口或实现类。
1. Collection的继承层次结构
2. Map的继承层次结构
3. 总结
由以上两图我们可以看出Java集合类有清晰的继承关系,有很多子接口和实现类。但是,并不是所有子接口或实现类都是最常用的。
下面我们列举出最常用的几个子接口和实现类:
Collection ——> List ——> ArrayList类
Collection ——> List ——> LinkedList类
Collection ——> Set ——> HashSet类
Collection ——> Set ——> SortedSet接口 ——> TreeSet类
Map ——> HashMap类
Map ——> SortedMap ——> TreeMap类
三. Collection接口和Iterator
1. Collection介绍
Collection接口是List接口和Set接口的父接口,它定义的方法可以用于操作List集合和Set集合。
Collection接口定义的方法
方法 | 描述 |
boolean add(Object o) | 该方法用于向集合里添加一个元素,添加成功返回true |
void clear() | 清除集合里的所有元素,将集合长度变为0 |
boolean contains(Object o) | 返回集合里是否包含指定元素 |
boolean containsAll(Collection c) | 返回集合里是否包含集合c里的所有元素 |
int hashCode() | 返回此collection的哈希码值 |
boolean isEmpty() | 返回集合是否为空,当集合长度为0时,返回true |
Iterator iterator() | 返回一个Iterator对象,用于遍历集合里的元素 |
boolean remove(Object o) | 删除集合中指定元素o,当集合中包含了一个或多个元素o时,这些元素将被删除,该方法将返回true |
boolean removeAll(Collection c) | 从集合中删除集合c里包含的所有元素,如果删除了一个或一个以上的元素,返回true |
boolean retainAll(Collection c) | 从集合中删除不在集合c里包含的元素,如果删除了一个或一个以上的元素,返回true |
int size() | 返回集合中的元素个数 |
Object[] toArray() | 该方法把集合转换成一个数组,所有集合元素变成对应的数组元素 |
【示例】
使用ArrayList实现类演示以上方法
2. Iterator
【介绍】
1. Collection接口的iterator()和toArray()方法都用于获得集合中的所有元素,前者返回一个Iterator对象,后者返回一个包含集合中所有元素的数组。
2. Iterator接口隐藏底层集合中的数据结构,提供遍历各种类型集合的统一接口。
【接口主要方法】
方法 | 描述 |
Boolean hasNext() | 如果被迭代的集合有下一个元素,则返回true |
Object next() | 返回集合里下一个元素 |
void remove() | 删除集合里上一次next方法返回的元素 |
【示例】
使用西游记人物作为元素,演示以上方法的使用
【for与iterator对比】
- Iterator的好处在于可以使用相同方式去遍历集合中元素,而不用考虑集合类的内部实现。
- 使用Iterator来遍历集合中元素,如果不再使用List转而使用Set来组织数据,则遍历元素的代码不用做任何修改
- 使用for来遍历,那所有遍历此集合的算法都得做相应调整,因为List有序,Set无序,结构不同,他们的访问算法也不一样
- for循环需要下标
【示例】
使用Collection接口演示iterator访问不需要下标。(Collection接口没有提供下标访问)
【foreach增强循环】
foreach遍历集合相当于获取迭代器,通过判断是否有下一个元素,执行操作。遍历数组相当于经典的for循环。
优点 | 缺点 |
遍历的时候更加简洁 | 不能同时遍历多个集合 |
3. List
【特点】
- List是一个有序集合,既存入集合的顺序和取出的顺序一致
- List集合允许添加的元素重复
List不单单继承了Collection的方法,还增加了一些新的方法。
方法 | 描述 |
void add(int index, Object element) | 将元素element插入到List的index处 |
boolean addAll(int index, Collection c) | 将集合c所包含的所有元素都插入在List集合的index处 |
Object get(int index) | 返回集合index处的元素 |
int indexOf(Object o) | 返回对象o在List集合中出现的位置索引 |
int lastIndexOf(Object o) | 返回对象o在List集合中最后一次出现的位置索引 |
Object remove(int index) | 删除并返回index索引处的元素 |
Object set(int index, Object element) | 将index索引处的元素替换成element对象,返回新元素 |
List subList(int fromIndex, int toIndex) | 返回从索引fromIndex(包含)到索引toIndex(不包含)处所有集合元素组成的子集合 |
【示例】
演示常用方法
3.1 ArrayList、Vector
【特点对比】
1. ArrayList和Vector都是基于数组实现的,两者用法差不多
2. ArrayList随机查询效率高,随机增删元素效率较低
3. Vector提供了一个Stack子类,模拟“栈”数据结构——”先进后出”
4. ArrayList是线程不安全的,Vector是线程安全的
【重点示例】
ArrayList中存放对象,在判断包含或者删除元素时,通过equals比较是否为同一个对象,然后进行操作
【示例】
将西游记取经团队5个成员放到Stack栈中,使用pop()和peek()操作元素,对比结果。
3.2 LinkedList
【特点】
- LinkedList是双向链表实现的
- 随机查询效率低,随机增删效率高
【LinkedList新增方法】
方法 | 描述 |
void addFirst(Object e) | 将指定元素插入该集合的开头 |
void addLast(Object e) | 将指定元素插入该集合结尾 |
boolean offerFirst(Object e) | 将指定元素插入该集合的开头,成功返回true |
boolean offerLast(Object e) | 将指定元素插入该集合结尾 |
boolean offer(Object e) | 将指定元素插入该集合结尾 |
Object getFirst() | 获取,但不删除集合第第一个元素 |
Object getLast() | 获取,但不删除集合最后一个元素 |
Object peekFirst() | 获取,但不删除该集合第一个元素,如果集合为空,则返回null |
Object peekLast() | 获取,但不删除该集合最后一个元素,如果集合为空,则返回null |
Object pollFirst() | 获取,并删除该集合第一个元素,如果集合为空,则返回null |
Object pollLast() | 获取,并删除该集合最后一个元素,如果集合为空,则返回null |
Object removeFirst() | 获取,并删除该集合的第一个元素 |
Object removeLast() | 获取,并删除该集合的最后一个元素 |
Object pop() | pop出该集合的第一个元素 |
void push(Object e) | 将一个元素push到集合 |
【示例】
示例演示以上方法
【总结】
- List主要有两个实现ArrayList和LinkedList,他们都是有顺序的,也就是放进去是什么顺序,取出来还是什么顺序
- ArrayList——遍历、查询数据比较快,添加和删除数据比较慢(基于可变数组)
- LinkedList——查询数据比较慢,添加和删除数据比较快(基于链表数据结构)
- Vector——Vector已经不建议使用,Vector中的方法都是同步的,效率慢,已经被ArrayList取代
- Stack——继承Vector实现的栈,栈结构是先进后出,但已被LinkedList取代
4. Set
【特点】
1. Set是一个无序集合,既存入集合的顺序和取出的顺序不一致
2. Set集合中元素不重复
【常用方法】
方法 | 描述 |
boolean add(E e) | 如果此set中尚未包含指定元素,则添加指定元素 |
boolean isEmpty() | 如果此set不包含任何元素,则返回true |
boolean contains(Object o) | 如果此set包含指定元素,则返回 true |
boolean remove(Object o) | 如果指定元素存在于此set中,则将其移除 |
int size() | 返回此set中的元素的数量 |
void clear() | 从此set中移除所有元素 |
【示例】
演示以上方法的使用
4.1 HashSet
HashSet是我们学习的重点,哈希原理我们在下面讲HashMap时,细讲。
4.2 TreeSet
TreeSet底层由TreeMap实现。可排序,默认自然升序。
【示例】
向TreeSet对象中添加几个元素。遍历打印出它们,显示有序。
【总结】
- HashSet底层由HashMap实现
- TreeSet底层由TreeMap实现
- <详解见HashMap、TreeMap>
5. Collections工具类和Comparable、Comparator比较器
5.1 Collections工具类
Collections是一个包装工具类。它包含有各种有关集合操作的静态多态方法,此类不能实例化,服务于Java的Collection接口。
【常用方法】
sort、reverse、fill、copy、max、min、swap等
【重点讲解:Sort排序】
其他方法,我们自行练习
public static <T extends Comparable<? super T>> void sort(List<T> list)
1. 根据元素的自然顺序 对指定列表按升序进行排序。列表中的所有元素都必须实现 Comparable 接口。
2. 此外,列表中的所有元素都必须是可相互比较的(也就是说,对于列表中的任何 e1 和 e2 元素,e1.compareTo(e2) 不得抛出 ClassCastException)。
【示例】
我们打开API查看String类,它是实现了Comparable接口的。所以,我们可以使用字符串对象为例,演示sort排序。
5.2 Comparable、Comparator比较器
对象排序,就是比较大小,要实现Comparable或Comparator比较器之一,才有资格做比较排序。
【介绍】
1. Comparable:与对象紧相关的比较器,可以称“第一方比较器”。
2. Comparator:此为与具体类无关的第三方比较器。
【示例】
1. 定义一个学生类,实现Comparable接口,使用学号进行Collections.sort排序
2. 定义一个学生类,实现Comparator接口,使用学号进行Collections.sort排序
五、总结
见:JavaSE-集合总结.xmind