Collection 接口
存储特点
-
以单个方式进行存储
-
不能放基本数据类型,也不存放java对象存储的都是对象的地址
-
未使用泛型:可以存储所有的Object类及其子类
-
使用泛型:存储泛型所指定的具体类型
Collection常用方法
boolean add(Object e) 添加元素
boolean remove(Object e) 移除元素
int size() 返回集合内元素个数
clear() 清空集合
contains(Object e) 判断是否包含某个元素
Object[] toArray() 转换为Object数组
isEmpty() 判断集合是否为空
iterator() 返回迭代器对象
List 接口
特点
-
有序可重复
-
有序:存进去和取出来的顺序一致
-
可重复:放进去1后可以再存1
-
List常用方法
void add(int index, E element) 向指定位置添加元素
int indexOf()返回元素第一次出现的下标
int lastIndexOf() 返回某个元素最后一次出现的下标
remove(int index) 删除指定下标的元素
set(int index,int element) 修改指定下标的元素
ArrayList
初始化
- 初始化容量是10,
- 底层是先创建一个长度为0的数组,
当添加第一个元素的时候,初始化容量为10
扩容
-
扩容为原容量的1.5倍,
-
在初始化时候给定一个预估计的容量,
减少扩容的次数是优化的一个重要手段
底层实现:数组
优缺点
检索效率高(每个元素占用空间大小相同,内存地址连续,知道首元素内存地址,然后知道下标,
通过数学表达式计算出元素的内存地址,所以效率较高),但向数组末尾添加元素效率很高,不受影响,
随机更删效率低,无法存储大数据量(很难找到一块非常大的连续空间)
非线程安全的
转换为线程安全的方法
将一个线程不安全的ArrayList 转换为线程安全的
import java.util.Collection
ArrayList myList = new ArrayList()
Collection.synchronizedLIst(myList);
// 此时mylist 就是线程安全的
LinkedList
初始化
初始化容量不存在
不存在扩容
底层实现:双向链表
优缺点
随机增删改查元素效率较高,因为增删元素不涉及到大量元素位移
查询效率较低,每一次查找某个元素都要从头结点开始进行遍历
Vector
初始化
初始化容量是10
扩容
底层扩容时扩容为原来容量的2倍 10-->20 (ArrayList 集合扩容特点是原来1.5倍)
底层实现:数组
优缺点
线程安全
但效率较低,有新的实现方案
Collections.sort() 对list进行排序时,list存储的元素需要实现comparable接口,或者在构造方法中传入比较器对象Comparator
Set 接口
特点
1.无序不可重复
无序:存进去和取出来的顺序不一致
不可重复:放进去1后无法再放1
HashSet
放在hashMap集合key部分的元素就是放到hashSet集合中
所以hashSet也需要重写hashcode方法和equals方法
SortedSet接口
TreeSet
TreeSet 集合元素特点
1.无序不可重复,但是存储的元素可以按照大小顺序进行排序,称为:可排序集合
2.无序,存进去和取出来的顺序不一致,且没有下标
底层 TreeMap
TreeSet集合中的元素,等同于放到TreeMap的key
放入TreeSet中的元素 要能够进行比较 排序,
自定义类型实现排序规则的方式有两种
-
实现comparable 接口 实现compareTo方法
-
在构造TreeSet 或者 TreeMap 集合的时候给它传一个比较器对象,
(匿名内部类的形式,或者新建一个比较器class传入)
如何选择?
比较规则不轻易改变 选择实现Comparable 接口,(例如 Integer,String,Date,)
比较规则有多种,并且需要进行切换,实现Comparator 接口
this - xxx 是升序
xxx - this 是降序
Set常用方法
和collection中常用方法基本一样
addAll(Collections c)
迭代方式
获取迭代器对象进行迭代,
集合的结构一旦发生变化,需要重新获取迭代器,
foreach 进行迭代
重要注意事项
存放在集合中的元素类型,需要重写equals方法
Map和Collection 没有继承关系
TreeSet集合,TreeMap集合采用的是,中序遍历方式
放到TreeSet或TreeMap集合key部分的时候,需要进行排序,实现方式有两种
- 放到集合中的元素实现java.lang.Comparable 接口 在compareTo方法写排序规则
- 在构造TreeSet 或者 TreeMap 集合的时候给它传一个比较器对象,(匿名内部类的形式,或者新建一个比较器class传入)
Comparable 和 Comparator 怎么选择 ?
比较规则不轻易改变 选择实现Comparable 接口,(例如 Integer,String,Date,)
比较规则有多种,并且需要进行切换,实现Comparator 接口
对set集合进行排序,需要先转换为list,然后再用Collections.sort()
构造方法中传入比较器对象,写比较规则
TreeSet<Integer> ts =new TreeSet<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
remove contain compareTo 方法底层调用的是equals方法
使用泛型
1.JDK 5.0 之后推出的新特性:泛型
2.泛型属于编译器阶段的新特性,只是给编译器参考的,运行阶段泛型没用
优点
-
保证了集合中元素的统一性
-
从集合中取出的元素类型是泛型指定类型,不需要进行大量的向下转型
缺点
-
导致集合中存储的元素缺乏多样性
-
大多数业务中,集合中元素类型还是统一的,所以还是能被接受的
自定义泛型
其他
JDK 8 之后引入了自动类型推断机制(又称为砖石表达式)
迭代时也需要指定迭代的泛型
Collections工具类
常用方法
Collections.synchronizedList(list) // 将线程不安全的ArrayList 转换为线程安全的
Collections.sort(wu); // 进行排序的list 存取的元素类型需要实现 comparable 接口
Collections.sort(myList 待排序数组, Comparator 比较器对象);
// 对set集合进行排序,需要先转换为list,然后再用Collections.sort()
集合之间转换
set和list之间的转换
// HashSet转换为ArrayList
HashSet set = new HashSet();
ArrayList list = new ArrayList(set);
// 使用构造方法即可完成转换
map和set之间的转换
Set set = map.entrySet()
文章评论