第一章:集合和泛型集合
一,集合
我们在之前的java学习中,学到了数组,数组是指定空间的存储单位,这会浪费空间,或者执行一些添加删除操作的时候,会很麻烦。那我们就要学一个存储空间可变的存储单位,就是集合。
Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中
上图是继承实现关系,浅蓝色是接口,蓝色是类。每个分支都有其特点。
1. Collection
特点:
- Collection 接口存储一组不唯一,无序的对象
方法:
2. List
特点:
List 接口存储一组可重复,有序(插入顺序)的对象
2.1 ArrayList
特点:
ArrayList实现了长度可变的数组,在内存中分配连续的空间,遍历元素和随机访问元素的效率比较高
ArrayList底层是一个数组,长度可变,数组的结构决定了它的查询效率高,但添加删除效率低。
常用方法:
2.2 LinkedList
特点:
LinkedList采用链表存储方式,插入、删除元素时效率比较高
LinkedList底层是一个双链表, 与ArrayList相比,LinkedList 的增加和删除对操作效率更高,而查找和修改的操作效率较低。
常用方法:
3. set
HashSet是Set接口常用的实现类,Set中存放对象的引用。
特点:
Set 接口存储一组不重复,无序的对象
方法:
一定要注意,Set没有get方法,不能使用get(index)
来获取元素。
3.1 HashSet
HashSet是Set接口常用的实现类
方法:
4. map
map是和Collection不同的分支,最常用的实现类是HashMap。
特点:存储的是键值对,key: value的键值映射。
Map接口常用方法:
4.1 HashMap
HashMap的底层是数组+链表的结构,这可以是它的 添加,删除,查找 操作,时间复杂度来到恐怖的O(1)。所以他其实是一个很理想的数据结构。
存储原理:
根据存储的值,经过哈希函数的计算得出结果,根据结果,放入值。好的哈希函数会让存储的值变得分散,不容易冲突,发生冲突则需要解决,HashMap是相同值存在数组的链表上的。
二,遍历集合的方式
1. for循环
for循环可以输出List的实现类的集合,因为有get()
方法所以可以遍历输出,Set的实现类不可以使用此方法。
示例:
for(int i=0;i<集合对象名.size();i++){
System.out.println(集合对象名.get(i));
}
2.迭代器循环
适用于所有的Collection分支。
示例:
Iterator it = 集合对象名.iterator();
System.out.println("----------迭代器循环打印----------");
while (it.hasNext()) {
System.out.println(it.next());
}
3.增强for循环
简化迭代器书写格式。(注意:增强for循环的底层还是使用了迭代器遍历。)
示例:
for(数据类型 变量名 :遍历的目标){
System.out.println(变量名);
}
三,泛型集合
- 泛型:将对象的类型作为参数,指定到其他类或者方法上,从而保证类型转换的安全性和稳定性
我们在上面写的代码用的集合默认都是Object类的,所以我们用增强for时要用Object的对象接收,当我们去主动声明集合类型时,我们就可以使用相同类型去接收,并且只能存储相同类型的对象。
泛型集合可以干什么?
泛型集合可以约束集合内的元素类型
典型泛型集合ArrayList、HashMap<K,V>、<K,V>表示该泛型集合中的元素类泛型集合中的数据不再转换为Object。除了指定了集合中的元素类型外,泛型集合和之前学习的集合的用法完全一样。
四,Collections工具类
- Java集合框架将针对不同数据结构算法的实现都保存在工具类中
- Collections类定义了一系列用于操作集合的静态方法
Collections类常用方法
Collections和Collection不同,前者是集合的操作类,后者是集合接口,Collections提供的常用静态方法
- sort():排序
- max()\min():查找最大\最小值
- reverse():反转指定列表中元素的顺序。
- swap():在指定的列表中的指定位置上交换元素。
注意:Collections类,实现一个类的对象之间比较大小,该类要实现Comparable接口,重写compareTo()方法