一.集合
1.什么是集合
存储对象的容器,面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,
存储对象,集合是存储对象最常用的一种方式。
集合的出现就是为了持有对象。
集合中可以存储任意类型的对象, 而且长度可变。在程序中有可能无法预先知道需要多少个对象,
那么用数组来装对象的话, 长度不好定义, 而集合解决了这样的问题。
2.集合和数组的区别
1.数组和集合类都是容器
2.数组长度是固定的,集合长度是可变的。数组中可以存储基本数据类型,集合中可以存储任意类型的对象。
集合类的特点:用于存储对象,长度是可变的,可以存储不同类型的对象。
3.数组的缺点
存储类型单一的数据容器,操作复杂(数组一旦声明好不可变)。
4.集合能做什么
1:将对象添加到集合
2:从集合中删除对象
3: 从集合中查找一个对象
4:从集合中修改一个对象就是增删改查
注意:集合和数组中存放的都是对象的引用而非对象本身
5.集合的分类
Java工程师对不同的容器进行了定义,虽然容器不同,但是还是有一些共性可以抽取最后抽取了
一个顶层接口,那么就形成了一个集合框架。
集合框架体系:
---|Collection: 单列集合
---|List: 有存储顺序, 可重复
---|ArrayList: 数组实现, 查找快, 增删慢
由于是数组实现, 在增和删的时候会牵扯到数组增容,
以及拷贝元素. 所以慢。数组是可以直接按索引查找, 所以查找时较快
---|LinkedList: 链表实现, 增删快, 查找慢
由于链表实现, 增加时只要让前一个元素记住自己就可以,
删除时让前一个元素记住后一个元素, 后一个元素记住前一个元素.
这样的增删效率较高但查询时需要一个一个的遍历, 所以效率较低
---|Vector: 和ArrayList原理相同, 但线程安全, 效率略低
和ArrayList实现方式相同, 但考虑了线程安全问题, 所以效率略低
---|Set: 无存储顺序, 不可重复
---|HashSet
---|TreeSet
---|LinkedHashSet
---| Map: 键值对
---|HashMap
---|TreeMap
---|HashTable
---|LinkedHashMap
为什么出现这么多集合容器,因为每一个容器对数据的存储方式不同,这种存储方式称之为数据结构(data structure)
注意:集合和数组中存放的都是对象的引用。
二.集合类(collection)
Collection接口有两个子接口:
List(链表|线性表)
Set(集)
特点:
Collection中描述的是集合共有的功能(CRUD), 单例集合的跟接口。
List 如果是实现了List接口的集合类,具备的特点: 有序,可重复。
Set 如果是实现了Set接口的集合类,具备特点: 无序,不可重复。
(1)Collection接口的共性方法
增加:
1:add() 将指定对象存储到容器中
add 方法的参数类型是Object 便于接收任意对象
2:addAll() 将指定集合中的元素添加到调用该方法和集合中
删除:
3:remove() 将指定的对象从集合中删除
4:removeAll() 将指定集合中的元素删除
5:clear() 清空集合中的所有元素
判断
6:isEmpty() 判断集合是否为空
7:contains() 判断集合中是否包含指定对象
8:containsAll() 判断集合中是否包含指定集合
使用equals()判断两个对象是否相等
获取:
9:int size() 返回集合容器的大小
转成数组
10: toArray() 集合转换数组
迭代器
11:iterator() 对 collection 进行迭代的迭代器
**迭代器的方法:**
1.hasNext() 问是否有元素可遍历。如果有元素可以遍历,返回true,否则返回false
2.next() 获取元素...
3.remove() 移除迭代器最后一次返回的元素。
遍历集合的元素
方式一: 可以使用toArray方法。
Object[] arr = c.toArray(); // toArray()把集合的元素存储到一个 Object的数组中返回。
for(int i = 0 ; i<arr.length ; i++){
System.out.print(arr[i]+",");
}
方式二:使用iterator迭代器遍历。
Iterator it = c.iterator(); //返回一个迭代器
while(it.hasNext()){ // hasNext() 问是否有元素可以遍历。
System.out.println("元素:"+ it.next()); //获取元素
}
//清空集合 的元素
while(it.hasNext()){
it.next();
it.remove();
}
疑问:iterator()方法返回的是一个接口类型,为什么接口又可以调用方法可以使用呢?
iterator 实际上返回的是iterator接口的实现类对象。
三.List集合接口
如果是实现了List接口的集合类,该集合类具备的特点:有序,可重复。
有序: 集合的有序不是指自然顺序,而是指添加进去的顺序与元素出来的顺序是一致的。
List接口中特有方法:
增加
1.void add(int index, E element) 指定位置添加元素
2.boolean addAll(int index, Collection c) 指定位置添加集合
删除
3.E remove(int index) 删除指定位置元素
修改
4.E set(int index, E element) 使用指定的元素替换指定索引值位置的元素,
返回的是需要替换的集合中的元素
查找
5.E get(int index) 根据索引值获取集合中的元素
6.int indexOf(Object o) 找出指定元素第一次出现在集合中的索引值
7.lastIndexOf(Object o) 找指定的元素最后一次出现在集合中的索引值
求子集合
8. List<E> subList(int fromIndex, int toIndex) // 不包含toIndex;
指定开始与结束的索引值截取集合中的元素。
迭代
listIterator() 是一个List接口中特有的迭代器,它继承了Iterator 接口
ListIterator特有的方法:
1.hasPrevious() 判断是否存在上一个元素。
2.previous() 当前指针先向上移动一个单位,然后再取出当前指针指向的元素。
3.next(); 先取出当前指针指向的元素,然后指针向下移动一个单位。
4.add(E e) 把当前有元素插入到当前指针指向的位置上。
5.set(E e) 替换迭代器最后一次返回的元素。
迭代器在变量元素的时候要注意事项:
在迭代器迭代元素的过程中,不允许使用集合对象改变集合中的元素 个数,如果需要添加或者删除
只能使用迭代器的方法进行操作。
如果使用过了集合对象改变集合中元素个数那么就会出现ConcurrentModificationException异常。
迭代元素的过程:
迭代器创建到使用结束的时间。
List接口中特有的方法具备的特点:
操作的方法都存在索引值。
只有List接口下面的集合类才具备索引值。其他接口下面的集合类都没有索引值。
四.List接口下的实现类–ArrayList类
ArrayList底层是维护了一个Object数组实现的,特点查询速度快,增删慢。
使用场景:
什么时候使用ArrayList: 如果目前的数据是查询比较多,增删比较少的时候,
那么就使用ArrayList存储这批数据。
ArrayList 特有的方法:
1.ensureCapacity(int minCapacity) 如有必要,增加此 ArrayList 实例的容量,
以确保它至少能够容纳最小容量参数所指定的元素数。
2.trimToSize() 将此 ArrayList 实例的容量调整为列表的当前大小。
ArrayList底层维护了一个Object[] 用于存储对象,默认数组的长度是10。
可以通过 new ArrayList(20)显式的指定用于存储对象的数组的长度。
当默认的或者指定的容量不够存储对象的时候,容量自动增长为原来的容量的1.5倍。
五.List接口下的实现类–LinkedList类
LinkedList底层是使用了链表数据结构实现的, 特点: 查询速度慢,增删快。
由于LinkedList:在内存中的地址不连续,需要让上一个元素记住下一个元素.
所以每个元素中保存的有下一个元素的位置.虽然也有角标,但是查找的时候,需要从头往下找,
显然是没有数组查找快的.但是,链表在插入新元素的时候,只需要让前一个元素记住新元素,
让新元素记住下一个元素就可以了.所以插入很快.
由于链表实现, 增加时只要让前一个元素记住自己就可以, 删除时让前一个元素记住后一个元素,
后一个元素记住前一个元素. 这样的增删效率较高。
但查询时需要一个一个的遍历, 所以效率较低。
Linkedlist特有的方法:
1:方法介绍
1. addFirst(E e) 将指定元素插入此列表的开头。
2.addLast(E e) 将指定元素添加到此列表的结尾。
3.getFirst() 返回此列表的第一个元素。
4.getLast() 返回此列表的最后一个元素。
5.removeFirst() 移除并返回此列表的第一个元素。
6.removeLast() 移除并返回此列表的最后一个元素。
2:数据结构
1:栈 (1.6): 主要是用于实现堆栈数据结构的存储方式。
先进后出
push() 将元素推入此列表所表示的堆栈。
pop() 从此列表所表示的堆栈处弹出一个元素。
2:队列(双端队列1.5): 主要是为了让你们可以使用LinkedList模拟队列数据结构的存储方式。
先进先出
offer() 将指定元素添加到此列表的末尾(最后一个元素)。
poll() 获取并移除此列表的头(第一个元素)
3:返回逆序的迭代器对象
descendingIterator() 返回逆序的迭代器对象,使用与listIterator一致。
六.List接口下的实现类–Vector类
Vector类 :底层也是维护了一个Object的数组实现的,实现与ArrayList是一样的,
但是Vector是线程安全的,操作效率低。
ArrayLsit与Vector的区别:
相同点: ArrayList与Vector底层都是使用了Object数组实现的。
不同点:
1. ArrayList是线程不同步的,操作效率高。
Vector是线程同步的,操作效率低。
2. ArrayList是JDK1.2出现,Vector是jdk1.0的时候出现的。