集合中的一些较为基础的面试题

集合中的一些基础的面试题

最近时间太忙,没能抽得出时间好好研究技术,所以就从3y大佬那转来点面试资料,弥补一下没学习的自己

Java容器可分为两大类:

CollectionMap

Collection 下有 ListSet

List集合:

  • ArrayList

  • LinkedList

  • Vector(了解,已过时)

Set集合:

  • HashSet
  • LinkedHashSet
  • TreeSet

Map集合:

  • HashMap

  • LinkedHashMap

  • TreeMap

  • ConcurrentHashMap

  • Hashtable(了解,已过时)

着重标出的那些就是我们用得最多的容器。

一、ArrayList和Vector的区别

共同点:

• 这两个类都实现了List接口,它们都是有序的集合(存储有序),底层是数组。我们可以按位置索引号取出某个元素,允许元素重复和为null

区别:

同步性:

– ArrayList是非同步的

– Vector是同步的

– 即便需要同步的时候,我们可以使用Collections工具类来构建出同步的ArrayList而不用Vector

扩容大小:

– Vector增长原来的一倍,ArrayList增长原来的0.5倍

二、HashMap和Hashtable的区别

共同点:

• 从存储结构和实现来讲基本上都是相同的,都是实现Map接口~

区别:

同步性:

– HashMap是非同步的

– Hashtable是同步的

– 需要同步的时候,我们往往不使用,而使用ConcurrentHashMapConcurrentHashMap基于JDK1.8源码剖析

是否允许为null:

– HashMap允许为null

– Hashtable不允许为null

contains方法

– 这知识点是在牛客网刷到的,没想到这种题还会有

– Hashtable有contains方法

– HashMap把Hashtable的contains方法去掉了,改成了containsValue和containsKey

继承不同:

– HashMap<K,V> extends AbstractMap<K,V>

– public class Hashtable<K,V> extends Dictionary<K,V>

三、List和Map的区别

共同点:

• 都是Java常用的容器,都是接口

不同点:

存储结构不同

– List是存储单列的集合

– Map存储的是key-value键值对的集合

元素是否可重复

– List允许元素重复

– Map不允许key重复

是否有序

– List集合是有序的(存储有序)

– Map集合是无序的(存储无序)

四、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()?

我们知道Set集合实际大都使用的是Map集合的put方法来添加元素

以HashSet为例,HashSet里的元素不能重复,在源码(HashMap)是这样体现的:

// 1. 如果key 相等
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
// 2. 修改对应的value
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}

添加元素的时候,如果key(也对应的Set集合的元素)相等,那么则修改value值。而在Set集合中,value值仅仅是一个Object对象罢了(该对象对Set本身而言是无用的)。

也就是说:Set集合如果添加的元素相同时,是根本没有插入的(仅修改了一个无用的value)!从源码(HashMap)中也看出来,==equals()方法都有使用

五、Collection和Collections的区别

  1. Collection是集合的上级接口,继承它的有Set和List接口

  2. Collections是集合的工具类,提供了一系列的静态方法对集合的搜索、查找、同步等操作

六、说出ArrayList,LinkedList的存储性能和特性

ArrayList的底层是数组,LinkedList的底层是双向链表。

• ArrayList它支持以角标位置进行索引出对应的元素(随机访问),而LinkedList则需要遍历整个链表来获取对应的元素。因此一般来说ArrayList的访问速度是要比LinkedList要快的

• ArrayList由于是数组,对于删除和修改而言消耗是比较大(复制和移动数组实现),LinkedList是双向链表删除和修改只需要修改对应的指针即可,消耗是很小的。因此一般来说LinkedList的增删速度是要比ArrayList要快的

6.1扩展:

ArrayList的增删未必就是比LinkedList要慢。

• 如果增删都是在末尾来操作【每次调用的都是remove()和add()】,此时ArrayList就不需要移动和复制数组来进行操作了。如果数据量有百万级的时,速度是会比LinkedList要快的

• 如果删除操作的位置是在中间。由于LinkedList的消耗主要是在遍历上,ArrayList的消耗主要是在移动和复制上(底层调用的是arraycopy()方法,是native方法)。

– LinkedList的遍历速度是要慢于ArrayList的复制移动速度的

如果数据量有百万级的时还是ArrayList要快

七、Enumeration和Iterator接口的区别

与Enumeration相比,Iterator更加安全,因为当一个集合正在被遍历的时候,它会阻止其它线程去修改集合

• 我们在做练习的时候,迭代时会不会经常出错,抛出ConcurrentModificationException异常,说我们在遍历的时候还在修改元素。

区别有三点:

• Iterator的方法名比Enumeration更科学

• Iterator有fail-fast机制,比Enumeration更安全

• Iterator能够删除元素,Enumeration并不能删除元素

八、ListIterator有什么特点

• ListIterator继承了Iterator接口,它用于遍历List集合的元素

• ListIterator可以实现双向遍历,添加元素,设置元素

看一下源码的方法就知道了:

在这里插入图片描述

九、Java中HashMap的key值要是为类对象则该类需要满足什么条件?

**需要同时重写该类的hashCode()****方法和它的equals()**方法

• 从源码可以得知,在插入元素的时候是先算出该对象的****hashCode。如果hashcode相等话的。那么表明该对象是存储在同一个位置上的。

• 如果调用equals()方法,两个key相同,则替换元素

• 如果调用equals()方法,两个key不相同,则说明该hashCode仅仅是碰巧相同,此时是散列冲突,将新增的元素放在桶子上

一般来说,我们会认为:只要两个对象的成员变量的值是相等的,那么我们就认为这两个对象是相等的!因为,Object底层比较的是两个对象的地址,而对我们开发来说这样的意义并不大~这也就为什么我们要重写equals()方法

重写了equals()方法,就要重写hashCode()的方法。因为equals()**认定了这两个对象相同,而同一个对象调用****hashCode()**方法时,是应该返回相同的值的!

十、ArrayList集合加入1万条数据,应该怎么提高效率

ArrayList的默认初始容量为10,要插入大量数据的时候需要不断扩容,而扩容是非常影响性能的。因此,现在明确了10万条数据了,我们可以直接在初始化的时候就设置****ArrayList的容量

这样就可以提高效率了~

十一、与Java集合框架相关的有哪些最好的实践

  1. 根据需要确定集合的类型。如果是单列的集合,我们考虑用Collection下的子接口ArrayList和Set。如果是映射,我们就考虑使用Map~

  2. 确定完我们的集合类型,我们接下来确定使用该集合类型下的哪个子类~我认为可以简单分成几个步骤:

– 是否需要同步

• 去找线程安全的集合类使用

– 迭代时是否需要有序(插入顺序有序)

• 去找Linked双向列表结构的

– 是否需要排序(自然顺序或者手动排序)

• 去找Tree红黑树类型的(JDK1.8)

我们就考虑使用Map~

  1. 确定完我们的集合类型,我们接下来确定使用该集合类型下的哪个子类~我认为可以简单分成几个步骤:

– 是否需要同步

• 去找线程安全的集合类使用

– 迭代时是否需要有序(插入顺序有序)

• 去找Linked双向列表结构的

– 是否需要排序(自然顺序或者手动排序)

• 去找Tree红黑树类型的(JDK1.8)

  1. 估算存放集合的数据量有多大,无论是List还是Map,它们实现动态增长,都是有性能消耗的。在初始集合的时候给出一个合理的容量会减少动态增长时的消耗~
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值