面试总结——集合篇

集合

1. 集合的概念

在Java中,我们经常需要存储一些对象,其中数组就可以实现这个要求,但数组长度不可变。而我们却长长需要一个长度可变的容器,于是集合就出现了。
集合是一个长度可变的,可保存同一数据类型的容器。

2.集合与数组的区别

  1. 长度:数组长度不可变,集合长度可变
  2. 内容:集合可以保存不同类型的元素,数组只能保存单一类型的元素。
  3. 元素:集合只能保存引用类型的元素,数组可以保存引用类型和基本类型。

3.集合的架构

在这里插入图片描述其中Collection接口和Map接口处于同级,List,Set和Queue接口是继承Collection接口。

List接口的实现类有ArrayList,LinkedList和Vector。

Set接口的实现类有HashSet,TreeSet

Map接口的实现类有HashMap,TreeMap和HashTable

4 详序

1. Collection接口

Collection接口是单列集合的最顶层接口,其定义了一些通用的方法。

add(E e)添加元素; clear()清空元素; remove(E e)移除元素; size()元素数量;

toArray()集合转数组; contains(E e)判断元素是否存在; isEmpty()判断集合是否为空;

2.List接口

特点:有索引,精准操作元素;

元素有序,元素存储和取出有序;

元素可重复,通过equals()判断元素是否重复。
它利用索引定义了一些特殊的方法:

get(int index,E e) 获取指定位置的元素;remove(int index)移除指定位置的元素;

add(int index,E e) 将元素添加到指定位置;set(int index,E e) 用元素替换指定位置的元素;

1.ArrayList

数据结构:数组

特点:查询快,增删慢。

底层分析:数组结构是有序的元素序列,在内存中开辟一段连续的空间,在空间中存放元素,每个空间都有编号,通过编号可以快速找到相应元素,因此查询快;数组初始化时长度是固定的,要想增删元素,必须创建一个新数组,把源数组的元素复制进来,随后源数组销毁,耗时长,因此增删慢。

2.LinkedList

数据结构:双向链表;
特点:查询慢,增删快;
底层分析:链表分为单向和双向,就是一条链子和两条链子的区别;多出的那条链子记录了元素的顺序,因此单向链表结构无序,双向链表结构有序;链表结构没有索引,因此查询慢;链表的增删只需在原有的基础上连上链子或切断链子,因此增删快。

此处对单向和双向链表的解释有错误,所谓单向链表和双向链表应该这样理解:

单向链表的每一个节点大致分为两个部分,一个用来记录该节点保存的值,另一个则是记录下一个节点的地址,所以单向链表的查询需要从第一个节点开始,一个个查找。

双向链表则是把每个节点分为三个部分,一个部分记录的是上一个节点的地址,一个部分记录的是下一个节点的地址。一个记录的是该节点保存的内容。

正确分析应该是:链表也是有序的元素序列,但在内存空间中,其分配的每个内存空间并不是连续的。在链表中进行查询时,单向链表需要从头开始查起,双向链表虽然可以从任意节点开始查起,但任然要遍历整个链表。所以链表结构查询慢,但在做增删操作时,只需修改节点保存的上一个/下一个节点的地址就可以。因此链表结构的增删操作相对于数组结构来说是快的。

特有方法:getFirst() 返回开头元素; getLast() 返回结尾元素;

pop() 从所在堆栈中获取一个元素; push(E e) 将元素推入所在堆栈;
addFirst(E e) 添加元素到开头,头插; addLast(E e) 添加元素到结尾,尾插;

3Vector

数据结构:数组;

特点:查询快,增删慢

底层分析:和ArrayList一样,都是数组实现,因此具有相似的特性,它们之间的区别在于Vector是线程安全的,效率低,ArrayList是线程不安全的,但效率高。

ps:Vector在JDK1.0就出现了,在JDK1.2集合出现的时候,Vector就归为List的实现类之一,这时候ArrayList才出现。Vector是一个古老的集合,《Java编程思想》中提到了它有一些遗留的缺点,因此不建议使用。

3 Set接口

特点:元素不可重复;

元素无序,存储及取出时顺序不一致;

没有索引,因此不能使用普通For循环遍历;

Set与Collection 接口中的方法基本一致,没有进行功能上的扩充;

1 HashSet

数据结构:JDK1.8之前:哈希表(数组+单向链表);JDK1.8之后:哈希表(数组+单向链表+红黑树),当链表长度超过阈值(8)时,链表将转换为红黑树。

特点:查询快,元素无序,元素不可重复,没有索引;

底层分析:哈希表底层用数组+单向链表实现,即使用链表处理冲突,同一Hash值的元素都存储在一个链表里,但是当位于一个链表中的元素较多,即Hash值相等的元素较多,通过key值依次查找的效率降低。JDK1.8之后,哈希表底层采用数据+单向链表+红黑树实现,当链表长度超过阈值(8)时,链表将转换为红黑树,极大缩短查询时间。

ps:哈希值是一个十进制的整数,是对象的地址值,是一个逻辑地址,不是实际存储的物理地址,由系统随机给出。Object类的int hashCode()方法,可以获取对象的哈希值。

2 LinkedHashSet

数据结构:JDK1.8之前:哈希表(数组+双向链表);JDK1.8之后:哈希表(数组+双向链表+红黑树),当链表长度超过阈值(8)时,链表将转换为红黑树。

特点:查询快,元素有序,元素不可重复,没有索引;

底层分析:作为HashSet的子类,只是比它多了一条链表,这条链表用来记录元素顺序,因此LinkedHashSet其中的元素有序。

3 TreeSet

数据结构:红黑树

特点:查询快,元素有序,元素不可重复,没有索引;

底层分析:TreeSet实现了继承于Set接口的SortedSet接口 ,它支持两种排序方法,自然排序和定制排序,自然排序的意思就是放入元素“a”,“b”,a会自然地排在b前面,其中还有几个特有方法。

first() 返回第一个元素; last() 返回最后一个元素;comparator() 返回排序比较器;

2 Map接口

特点:元素包含两个值(key,value)即键值对, key不允许重复,value可以重复, key与value是一一对应的。元素无序;

Map接口是双列集合的最顶层接口,定义了一些通用的方法。

put(key , value) 添加元素; remove(key) 删除key对应元素;

containsKey(key) 判断是否存在key对应元素;get(key) 获取key对应元素;

KeySet() 获取所有的key,存到Set集合中;entrySet() 获取所有的元素,存到Set集合中;

ps:Map集合必须保证key唯一,作为key,必须重写hashCode方法和equals方法,以保证key唯一。

1HashMap

数据结构:JDK1.8之前:哈希表(数组+单向链表);JDK1.8之后:哈希表(数组+单向链表+红黑树),当链表长度超过阈值(8)时,链表将转换为红黑树。

特点:查询快,元素无序,key不允许重复但可以为null,value可以重复。

底层分析:和HashSet底层相类似,不赘述。

LinkedHashMap

数据结构:JDK1.8之前:哈希表(数组+双向链表);JDK1.8之后:哈希表(数组+双向链表+红黑树),当链表长度超过阈值(8)时,链表将转换为红黑树。

特点:查询快,元素有序,key不允许重复但可以为null,value可以重复。

底层分析:和LinkedHashSet底层相类似,不赘述。

HashTable

数据结构:哈希表

特点:查询快,元素无序,key不允许重复并且不可以为null,value可以重复。

底层分析:HashTable和Vector一样是古老的集合,有遗留缺陷,在JDK1.2之后 被更先进的集合取代了;HashTable是线程安全的,速度慢,HashMap是线程不安全的,速度快;

ps:HashTable的子类Properties现在依然活跃,Properties集合是一个唯一和IO流结合的集合。

TreeMap

数据结构:红黑树

特点:查询快,元素有序,key不允许重复并且不可以为null,value可以重复。

底层分析:和TreeSet底层相类似,不赘述。

该文大部分引用他人博客内容

原文链接:https://blog.csdn.net/weixin_42559574/article/details/108203595

面试遇到的问题:

  1. Map如何转换为Set
    Set<Map.Entry<Object, Object>> set = map.entrySet();

  2. Map集合中如何确认两个元素是否重复
    先调用HashCode()获取两个元素的hash值,比较这两个值是否相等。在调用equlas()方法比较两个元素的值是否相等。

  3. ArrayList和LinkedList的区别
    两者的区别主要是基于数据结构不同而照成的不同。ArrayList查找快,增删慢,LinkedList查找慢,增删快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值