Java集合三大类
Java中的集合包括三大类:Set(集)、List(列表)和Map(映射),它们都处于java.util包中,Set、List和Map都是接口,它们有各自的实现类。
Set的实现类主要有HashSet和TreeSet,List的实现类主要有ArrayList,
Map的实现类主要有HashMap和TreeMap。
Collection是最基本的集合接口,声明了适用于JAVA集合的通用方法,
List 和 Set都继承自collection接口。
(1)List概述
- 允许重复的对象。
- 可以插入多个null元素。
- 是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。
- 常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。
(2)Set概述
- 不允许重复对象
- 无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。
- 只允许一个 null 元素
- Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。
(3)Map概述
- Map不是collection的子接口或者实现类。Map是一个接口。
- Map的每个 Entry 都持有两个对象,也就是一个键一个值,Map可能会持有相同的值对象但键对象必须是唯一的。
- TreeMap也通过Comparator或者Comparable维护了一个排序顺序。
- Map里你可以拥有随意多个null 值但最多只能有一个null键。
- Map接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)
集合间的区别与联系
List,Set和Map的区别
List:有序,可以存在重复元素
集合中的对象按索引位置排序,可以有重复对象,
允许按照对象在集合中的索引位置检索对象。
Set:无序,不允许存在重复的元素
集合中的对象不按特定方式排序,排序方式有默认排序和定制排序,
定制排序需要实现Comparator接口。
与list对比,检查元素效率低下,删除和插入的效率高,插入和删除不会引起元素的位置变化。
Map:集合中的元素都包含一对键对象和值对象,键对象不可以重复,值对象可以重复。
ArrayList、Vector和LinkedList的区别
面试题:
Q:ArrayList和LinkedList区别?
A:
(1)数据结构不同。ArrayList 底层数据结构是动态数组,LinkedList 底层数据结构是双向链表
(2)内存开销不同。如果列表很大很大,ArrayList 和 LinkedList 在内存的使用上也有所不同。
LinkedList 的每个元素都有更多开销,因为要存储上一个和下一个元素的地址。ArrayList 没有这样的开销。
(3)作用不同。ArrayList 只能用作列表;LinkedList 可以用作列表或者队列,因为它还实现了 Deque 接口。
(4)效率不同。当通过索引随机访问集合时(get和set操作,即查询和修改操作),ArrayList 比 LinkedList 的效率高,
因为 ArrayList 由于时数组结构,通过索引查询的时间复杂度是O(1);而 LinkedList 是链表结构,通过索引查询是通过node(index)
方法遍历查找,时间复杂度是O(n)。不走索引都需要遍历集合,效率基本相同。当对集合进行增加和删除操作时(add和remove操作),
LinkedList 一般比 ArrayList 的效率高,增加元素时,LinkedList 需要根据增加的节点位置操作链表连接节点,中间节点也是需要循
环获取到的,而 ArrayList 如果超过数组长度需要进行动态扩容,在不触发 ArrayList 的动态扩容情况下,ArrayList 的效率甚至要
高于 LinkedList ;但是若触发 ArrayList 的动态扩容,LinkedList 效率要高于 ArrayList 。删除元素时, LinkedList 除了
有单独的方法移除头尾节点,其它节点都需要循环集合定位到该元素,再断连即可,ArrayList 如果是通过索引(remove(int index)方
法)查询到元素,直接获取即可;如果是通过元素值(remove(object o)方法)查询该元素,也需要循环获取元素,然后删除元素后再通过
System.arraycopy()方法将该元素的后面的元素往前移动一位;所以单就删除动作来说LinkedList 效率要高于 ArrayList。
Q:LinkedList为什么查改慢,增删快?
A:
查改慢:因为查改都需要先定位到元素,由于LinkedList 是链表结构,查询元素是通过node(index)方法遍历集合查找,
时间复杂度是O(n)。
(1)假如集合size=100,要取index=40的元素,根据源码,100>>1=50,40<50,需要从前往后循环,循环40遍取出node.item.
(2)但是如果取最前面和最后面的元素可以通过getFirst和getLast方法获取,比较快,此时时间复杂度是O(1)
增删快:增加元素时,LinkedList 需要根据增加的节点位置操作链表连接节点,中间节点也是需要循环获取到的;
删除元素时, LinkedList 除了有单独的方法移除头尾节点,其它节点都需要循环集合定位到该元素,再断连即可,
单单就增加和删除的动作来看,只需要链接新的元素,而不必修改列表中剩余的元素,无论列表尺寸如何变化,其代价大致相同。
原文链接:https://blog.csdn.net/qq_46601365/article/details/130367911
补充:
(1)List:列表
最重要的特点就是:它保证维护元素特定的顺序,List为Collection添加了很多方法,使得能够向List中间插入语移除元素。
(2)ArrayList: 动态数组
即由数组实现的List,允许对元素进行快速随机访问,查找元素的效率较高,插入元素和删除元素效率低,因为会引起其他元素位置发生变化
(3)LinkedList: 链表,队列,堆栈
对顺序访问进行了优化,向List中间插入与删除的开销并不大,随机访问则行对较慢,(使用ArrayList代替)还有下列方法:addFirst(),addLast(),getFirst(),getLast(),removeFirst(),romoveLast().这些方法使得LinkedList可以当作堆栈,队列和双向队列使用。
HashSet、LinkedHashSet和TreeSet的区别
Set:常用于集合元素去重 。 无序,唯一
HashSet:常用于集合元素去重
底层数据结构是哈希表(数据无序,唯一)
可以放入null,但只能放入一个null,两者中的值都不能重复,如数据库中唯一约束
依赖两个方法:hashCode()和equals()来保证元素的唯一性
以哈希表的形式存放元素,插入删除速度很快
只是通用的存储数据的集合
LinkedHashSet:常用于集合元素去重与排序
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
由链表保证元素有序
由哈希表保证元素唯一
用于保证FIFO即有序的集合(先进先出)
TreeSet
底层数据结构是红黑树。(唯一,有序)
Treeset中的数据是自动排好序的,不允许放入null值。
通过自然排序和比较器排序保证元素有序
根据比较的返回值是否是0来决定来保证元素唯一性
主要用于排序
HashSet与HashMap的区别
HashMap与HashTable有什么区别?对比Hashtable VS HashMap
两者都是用key-value方式获取数据。Hashtable是原始集合类之一(也称作遗留类)。HashMap作为新集合框架的一部分在Java2的1.2版本中加入。它们之间有一下区别:
● HashMap和Hashtable大致是等同的,除了非同步和空值(HashMap允许null值作为key和value,而Hashtable不可以)。
● HashMap没法保证映射的顺序一直不变,但是作为HashMap的子类LinkedHashMap,如果想要预知的顺序迭代(默认按照插入顺序),你可以很轻易的置换为HashMap,如果使用Hashtable就没那么容易了。
● HashMap不是同步的,而Hashtable是同步的。
● 迭代HashMap采用快速失败机制,而Hashtable不是,所以这是设计的考虑点。
TreeSet和TreeMap的联系和区别
与HashSet完全类似,TreeSet里面绝大部分方法都是直接调用TreeMap方法来实现的。
相同点:
- TreeMap和TreeSet都是非同步集合,因此他们不能在多线程之间共享,不过可以使用方法Collections.synchroinzedMap()来实现同步。
- 运行速度都要比Hash集合慢,他们内部对元素的操作时间复杂度为O(logN),而HashMap/HashSet则为O(1)。
- TreeMap和TreeSet都是有序的集合,也就是说他们存储的值都是排好序的。
不同点:
最主要的区别就是TreeSet和TreeMap分别实现Set和Map接口
- TreeSet只存储一个对象,而TreeMap存储两个对象Key和Value(仅仅key对象有序)
- TreeSet中不能有重复对象,而TreeMap中value可以存在重复对象。
- TreeMap的底层采用红黑树的实现,完成数据有序的插入,排序。
什么时候用Set什么时候用Map呢?
List,Set和Map的联系和使用场景
Collection集合适用场景分析
ArrayList和LinkedList的使用场景
- 若经常使用索引对容器中的元素进行访问,那么使用List 。如果知道索引,那么 List 的实现类比如 ArrayList 可以提供更快速的访问,因为LinkedList要移动指针。如果经常添加、删除元素的,选LinkedList。
- 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
- ArrayList是基于数组的,LinkedList是基于链表的。
Set和Map的使用场景
- 如果希望保证插入元素的唯一性,不希望出现重复值,那么可以选择一个 Set 的实现类,比如 HashSet、LinkedHashSet 或者 TreeSet。
- 所有 Set 的实现类都遵循了统一约束比如唯一性,而且还提供了额外的特性。比如 TreeSet 还是一个 SortedSet,所有存储于 TreeSet 中的元素可以使用 Java 里的 Comparator 或者 Comparable 进行排序。LinkedHashSet 也按照元素的插入顺序对它们进行存储。
- 如果是希望以键值的形式进行数据存储,那么用Map。根据需要选择Hashtable、HashMap或TreeMap。
Hashtable和HashMap的使用场景
基本的不同点是Hashtable同步,HashMap不是的。
所以无论什么时候有多个线程访问相同实例的可能时,就应该使用Hashtable,反之使用HashMap。非线程安全的数据结构能带来更好的性能。
如果在将来有一种可能,你需要按顺序获得键值对的方案时,HashMap是一个很好的选择。
因为有HashMap的一个子类 LinkedHashMap。所以如果你想可预测的按顺序迭代(默认按插入的顺序),
你可以很方便用LinkedHashMap替换HashMap,反观要是使用的Hashtable就没那么简单了。
同时如果有多个线程访问HashMap,Collections.synchronizedMap()可以代替,总的来说HashMap更灵活。