Java集合框架
1. 集合
1.1 什么是集合
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式(容器)
Java中集合也是类,真正用来存储东西的是某种集合类的实例对象
Java集合是java提供的工具包,包含了常用的数据结构:集合、链表、队列、栈、数组、映射等。Java集合工具包位置是java.util.*
Java集合主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections)
1.2 集合和数组的区别
集合
1.长度是可变的
2.只能用于存储对象的引用
3.对象可以是不同类型
数组
1.长度是固定的
2.可以存储基本数据类型
3.也可以存储对象的应用
4.必须是相同类型
2. Collection接口
2.1 Collection说明
Collection 层次结构中的根接口。
Collection 表示一组对象,这些对象也称为 Collection 的元素。
一些 Collection 允许有重复的元素,而另一些则不允许。
Collection接口有两个子接口
List接口:可存放重复元素,元素存取是“有序”的。
Set接口:不可以存放重复元素,通常元素存取是“无序”的,也有一些实现类元素是“有序”的。
(ps:“有序”,“无序”指的是存放元素时是否会记住元素存放的顺序,并非对元素进行“排序”)
2.2 Collection接口方法
添加:
boolean add(Object e)
boolean addAll(Collection c)
删除:
boolean remove(Object o)
boolean removeAll(Collection c)
查询:
int size()
判断:
boolean isEmpty()
boolean contains(Object obj)
boolean containsAll(Collection c)
返回包含此 collection 中所有元素的数组。
Object toArray()
2.3 迭代器
迭代操作
Iterator iterator()
说明:
1.迭代器不保证取出元素的顺序和存入的顺序一致,“有序”是靠集合实例本身保证的。
2.迭代器本身是一个接口,该方法返回的是一个迭代器实例对象,通常使用的是接口多态使用迭代器
3.迭代器中常用的两个方法是:
boolean hasNext():判断是否有下一个元素
Object next():取出下一个元素
Collection c = new ArrayList(); //创建集合对象 Iterator it = c.iterator(); //获取此集合的迭代器 while(it.haxNext()){ //遍历这个集合 Object o = it.next(); }
3. List说明
3.1 List接口中常用类
ArrayList: 线程不安全,查询速度快,底层用的是数组,增删慢
LinkedList: 线程不安全,链表结构,增删速度快,查询慢
Vector: 线程安全,但速度慢,已被ArrayList替代
3.2 List接口特有的方法
方法 | 说明 |
void add(int index, Object element) | 在列表的指定位置插入指定元素。 |
Object get(int index) | 返回列表中指定位置的元素。 |
Object set(int index, Object element) |
用指定元素替换列表中指定位置的元素。 |
3.3 增强for循环
说明:增强for循环是迭代器的一种简化方式
格式:
for(Object obj : c){
//do something with obj
}
Object 元素类型
obj 迭代变量名
c 集合名
3.4 List接口遍历的方式
- 迭代器遍历
- 增强for循环
- 普通for循环配合使用get方法
3.5 迭代器Iterator
迭代是取出集合中元素的一种方式
因为Collection中有iterator方法,所以每一个子类集合对象都具备迭代器
两种用法:(常用第二种)
第一种
for(Iterator iter = iterator();iter.hasNext();){ System.out.println(iter.next()); }
第二种
Iterator iter = l.iterator(); while(iter.hasNext()){ System.out.println(iter.next()); }
迭代器在Collcection接口中是通用的。
迭代器的next方法返回值类型是Object,所以要记得类型转换。
4. Array List
4.1 ArrayList概念&去重
通过数组来实现,擅长读操作,有容量概念,扩容发展50%。
ArrayList对自定义类对象去重思路:
思路一: 新建一个集合,判断新集合中是否存在(contains)旧集合中的元素,不存在则添加(add)
思路二: 使用双重for循环, 从前往后和从后往前两种方式进行比较。
4.2 并发修改异常
在使用迭代器和增强for循环遍历ArrayList的时候,使用集合本身的方法修改了集合,将导致并发修改异常:ConcurrentModificationException(两个不要交叉使用)
foreach本质上:是使用了迭代器
正确做法:
- 使用迭代器遍历,使用迭代器删除(修改)元素
- 使用集合本身遍历且非foreach,使用集合本身方法删除(修改)元素
5. LinkedList
内部通过链表实现,擅长写操作,通过指针引用实现,检索的对象时从两头检索,看索引位于哪个半段范围中。内部存放了首尾两个节点,元素通过node连接在一起。Node由item 、 prev、 next构成,检索最坏情况不会超过半数。
集合 | 说明/实现 | 结构 | 线程安全 | 特有方法 |
List | 有序,可重复 | 判断是否存在的标准是判断equals是否相等。同时支持null。 | ||
ArrayList | 底层通过数组实现,擅长读,容量概念,默认10超过则扩容(通过拷贝,扩容一半) | 不安全 | add() | |
LinkedList | 底层通过链表实现,擅长写,通过指针引用实现。 | 不安全 | addFirst()/addLast()/remove() | |
Vector | 可以看作线程安全版的ArrayList | 安全 | ||
Set | 无序,不重复 | |||
HashSet | 线程不安全,存取速度快 | 不安全 |
重写hashCode()原则:让所有的成员变量都参与计算 |
|
LinkedHashSet | 在HashSet基础上增加了链表:记录元素的顺序,无特殊方法 | |||
TreeSet | ||||
Map | Key-Value, Key有Set特点 | put() | ||
Hashtable | 线程安全,速度慢,不允许存放null键,null值,已被HashMap替代。 | 安全 | ||
HashMap |
数组+链表实现,线程不安全,速度快,允许存放null键,null值 HashMap的底层实现是散列表,因此它内部存储的元素是无序的 |
不安全 | ||
TreeMap |
TreeMap的底层实现是红黑树,所以它内部的元素的有序的,可以自动排序。 排序的依据是自然序或者是创建TreeMap时所提供的比较器(Comparator)对象。 根据使用的构造方法决定是使用元素本身可比性,还是使用集合的可比性 |
不安全 |