赞
踩
Java中的集合包括三大类:Set(集)、List(列表)和Map(映射),它们都处于java.util包中,Set、List和Map都是接口,它们有各自的实现类。
Set的实现类主要有HashSet和TreeSet,List的实现类主要有ArrayList,
Map的实现类主要有HashMap和TreeMap。
Collection是最基本的集合接口,声明了适用于JAVA集合的通用方法,
List 和 Set都继承自collection接口。
List:有序,可以存在重复元素
集合中的对象按索引位置排序,可以有重复对象,
允许按照对象在集合中的索引位置检索对象。
Set:无序,不允许存在重复的元素
集合中的对象不按特定方式排序,排序方式有默认排序和定制排序,
定制排序需要实现Comparator接口。
与list对比,检查元素效率低下,删除和插入的效率高,插入和删除不会引起元素的位置变化。
Map:集合中的元素都包含一对键对象和值对象,键对象不可以重复,值对象可以重复。
面试题:
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可以当作堆栈,队列和双向队列使用。
Set:常用于集合元素去重 。 无序,唯一
HashSet:常用于集合元素去重
底层数据结构是哈希表(数据无序,唯一)
可以放入null,但只能放入一个null,两者中的值都不能重复,如数据库中唯一约束
依赖两个方法:hashCode()和equals()来保证元素的唯一性
以哈希表的形式存放元素,插入删除速度很快
只是通用的存储数据的集合
LinkedHashSet:常用于集合元素去重与排序
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
由链表保证元素有序
由哈希表保证元素唯一
用于保证FIFO即有序的集合(先进先出)
TreeSet
底层数据结构是红黑树。(唯一,有序)
Treeset中的数据是自动排好序的,不允许放入null值。
通过自然排序和比较器排序保证元素有序
根据比较的返回值是否是0来决定来保证元素唯一性
主要用于排序
两者都是用key-value方式获取数据。Hashtable是原始集合类之一(也称作遗留类)。HashMap作为新集合框架的一部分在Java2的1.2版本中加入。它们之间有一下区别:
● HashMap和Hashtable大致是等同的,除了非同步和空值(HashMap允许null值作为key和value,而Hashtable不可以)。
● HashMap没法保证映射的顺序一直不变,但是作为HashMap的子类LinkedHashMap,如果想要预知的顺序迭代(默认按照插入顺序),你可以很轻易的置换为HashMap,如果使用Hashtable就没那么容易了。
● HashMap不是同步的,而Hashtable是同步的。
● 迭代HashMap采用快速失败机制,而Hashtable不是,所以这是设计的考虑点。
与HashSet完全类似,TreeSet里面绝大部分方法都是直接调用TreeMap方法来实现的。
最主要的区别就是TreeSet和TreeMap分别实现Set和Map接口
基本的不同点是Hashtable同步,HashMap不是的。
所以无论什么时候有多个线程访问相同实例的可能时,就应该使用Hashtable,反之使用HashMap。非线程安全的数据结构能带来更好的性能。
如果在将来有一种可能,你需要按顺序获得键值对的方案时,HashMap是一个很好的选择。
因为有HashMap的一个子类 LinkedHashMap。所以如果你想可预测的按顺序迭代(默认按插入的顺序),
你可以很方便用LinkedHashMap替换HashMap,反观要是使用的Hashtable就没那么简单了。
同时如果有多个线程访问HashMap,Collections.synchronizedMap()可以代替,总的来说HashMap更灵活。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。