java集合详解
一、常用的集合
1、Collection 接口的接口 对象的集合(单列集合){
----------->List 接口:元素按进入先后有序保存,可重复{
--------------->LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
--------------->ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
-------------->Vector 接口实现类 数组, 同步, 线程安全 (Stack 是Vector类的实现类)
}
----------->Set 接口: 仅接收一次,不可重复,并做内部排序{
--------------->HashSet 使用hash表(数组)存储元素
--------------->LinkedHashSet 链表维护元素的插入次序
--------------->TreeSet 底层实现为二叉树,元素排好序
}
}
2.Map 接口 键值对的集合 (双列集合){
----------->Hashtable 接口实现类, 同步, 线程安全
----------->HashMap 接口实现类 ,没有同步, 线程不安全{
------------->LinkedHashMap 双向链表和哈希表实现
------------->WeakHashMap
}
----------->TreeMap 红黑树对所有的key进行排序
----------->IdentifyHashMap
}
二、对比
有序性:
①list是按插入顺序排序
②set是无序的
唯一性:
①list存储数据可重复
②set存储数据唯一
获取元素:
①list可以通过索引直接操作元素
②set不能根据索引获取元素
2.ArrayList和LinkedList和Vector
(注:数据结构的存储方式只有两种:数组-顺序存储和链表-链式存储)
①ArrayList:查询快,增删慢,线程不安全,效率高,可以存储重复元素
底层数据结构是数组,数组是紧凑连续存储,可以随机访问,可通过索引快速定位对应元素,故查询快;而想在数组中间插入和删除,每次必须移动
后面的数据以保持连续,就造成速率慢。
②LinkedList:查询慢,增删快,线程不安全,效率高,可以存储重复元素
底层数据结构是链表,链表因为元素不连续,而是靠指针指向下一个元素的位置,所以不存在数组的扩容问题;
如果知道某一元素的前驱和后驱,操作指针即可删除该元素或者插入新元素,时间复杂度O(1),增删快。
但是正因为存储空间不连续,你无法根据一个索引算出对应元素的地址,所以不能随机访问,查询就慢;而且由于每个元素必须存储指向前后元素位置的指针,会消耗相对更多的储存空间。
③Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素 ;这里vector为何是线程安全的,因为它源码中可以看出Vector类中的方法很多有synchronized进行修饰
同时这也导致了其效率低下相比较ArrayList
① HashSet:底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素;
元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。
② LinkedHashSet:底层数据结构采用链表和哈希表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。
③TreeSet底层数据结构采用二叉树来实现,元素唯一且已经排好序;唯一性同样需要重写hashCode和equals()方法,二叉树结构保证了元素的有序性。
根据构造方法不同,分为自然排序(无参构造)和比较器排序(有参构造),自然排序要求元素必须实现Compareable接口,并重写里面的compareTo()方法,元素通过比较返回的int值来判断排序序列,返回0说明两个对象相同,不需要存储;比较器排需要在TreeSet初始化是时候传入一个实现Comparator接口的比较器对象,或者采用匿名内部类的方式new一个Comparator对象,重写里面的compare()方法;