2021-10-13

Java面试篇之容器篇

其中ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap是常用的类,要重点掌握
Collection
存放独立元素的序列。Collection下又有三个子接口,List,Set,Queue。

List
一个有序的Collection(也称序列),元素可以重复。确切的讲,列表通常允许满足 e1.equals(e2) 的元素对 e1 和 e2,并且如果列表本身允许 null 元素的话,通常它们允许多个 null 元素。实现List的有:ArrayList、LinkedList、Vector、Stack等。

Set
一个不包括重复元素(包括可变对象)的Collection,是一种无序的集合。Set不包含满 a.equals(b) 的元素对a和b,并且最多有一个null。实现Set的接口有:EnumSet、HashSet、TreeSet等。

Queue
一种队列则是双端队列,支持在头、尾两端插入和移除元素,主要包括:ArrayDeque、LinkedBlockingDeque、LinkedList。另一种是阻塞式队列,队列满了以后再插入元素则会抛出异常,主要包括ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue。

Map
存放key-value型的元素对。

1.常见容器:

String,数组以及java.util下面的集合类
List:存放有序,列表存储,元素可重复 ArrayList LinkedList Vector
Set:无序,元素不可重复 HashSet TreeSet
Map:无序,元素可重复 HashMap TreeMap LinkedHashMap HashTable

2.Collection 和 Collections 有什么区别?

Collection是集合类的一个顶级接口,它提供了对集合对象进行基本操作的通用接口方法.
Collections是集合类的一个工具类,它提供了一系列的静态方法,用于对集合中元素进行排序,搜索以及线程同步等操作.

3.List、Set、Map 之间的区别是什么?

  • List: 可以允许重复的对象;
    可以插入多个null元素;
    有序,输入顺序就是输出顺序;
  • Set: 不允许重复对象;
    无序,且只允许一个null对象;
  • Map: 存储键值对,只能有唯一的key,value可以重复
    只能有一个null键

4.HashMap 和 Hashtable 有什么区别?

一. HashMap可以接受null键和值,HashTable不行
二. HashTable是线程安全的,通过synchronized来保证,而HashMap线程不安全
三. HashMap的迭代器是fail-fast迭代器,而HashTable的enumerator迭代器不是fail-fast.

5.如何决定使用 HashMap 还是 TreeMap?

HashMap基于散列表实现,适用于查询频繁的情况
TreeMap基于红黑树实现,适用于创建比较多的情况.且TreeMap存储数据是按照字母表的顺序存储的,如果对顺序有要求也可以选用TreeMap.

6.说一下 HashMap 的实现原理?(重点!!!)

数组+链表,初始16,0.75扩容,数据存在内部类Map.Entry中,其中包含key value hashcode和next.
详细👇

  1. HashMap 基于 Hash 算法实现的,我们通过 put(key,value)存储,get(key)来获取。
  2. 当传入 key 时,HashMap 会根据 key. hashCode() 计算出 hash 值,根据 hash 值将 value 保存在 bucket 里。
  3. 当计算出的 hash 值相同时,我们称之为 hash 冲突,HashMap 的做法是用链表和红黑树存储相同 hash 值的 value。
  4. 当 hash 冲突的个数比较少时,使用链表否则使用红黑树。
  5. HashMap 对应的线程安全类是 ConcurrentHashMap

7. HashMap的工作原理

  1. HashMap是面向查询优化的数据结构,查询性能优异。
  2. 在其内部利用数组存储数据。
  3. 插入数据时,先根据Key的HashCode计算出数组的下标位置,再利用Key的equals()方法检查是否以存在重复的Key,如果不重复直接存储到数组中,如果重复就作为链表存储到散列桶中。
  4. 插入的数据和数组容量的比值大于加载因子则进行数组扩容,并重新散列,默认的加载因子为“0.75”。
  5. 查询时,先根据Key的HashCode计算出数组的下标位置,再利用Key的equals()方法检查到Key的位置,如果找到返回Key对应的Value,否则返回Null。
  6. 由于利用Key的HashCode直接计算出数据的存储位置,由于直接确定数据的存储位置,相对于其他查找方式,查询效率非常高。

8.说一下 HashSet 的实现原理?

HashSet基于HashMap实现,默认构造函数是构造一个初始容量为16的HashMap,所有放入HashSet
集合的元素实际上由HashMap的key来保存,而value则保存了一个PRESENT的静态Object对象,因为元素都保存在key中,所以才能不重复.

9.ArrayList和LinkList的区别?

  • ArrayList(底层基于动态数组):
    优点:get和set调用花费常数时间,也就是查询的速度快
    缺点:新项的插入和现有项的删除代价昂贵,也就是添加删除的速度慢
  • LinkedList(基于链表实现,底层是循环双向链表):
    优点:新项的插入和和现有项的删除开销很小,即添加和删除的速度快
    缺点:对get和set的调用花费昂贵,不适合做查询
    另一种说法👇
  • ArrayList底层基于动态数组,LinkedList基于链表实现,底层是循环双向链表

  • 对于随机访问get和set,ArrayList优于LinkedList.

  • 对于新增add和删除remove,LinkedList比较快

    10.ArrayList的扩容机制

    jdk7,底层创建了长度是10的Object[]数组,如果添加导致数组容量不够,则扩容,扩容为原来的1.5倍,同时将原数组中的数据复制到新的数组中。

    jdk8,刚开始调用构造方法时并没有创造长度为10的Object[]数组,而是第一次调用add()时,底层才创建了长度为10的数组

    11.ArrayList 和 Vector 的区别

    ArrayList是List接口的主要实现类,底层使用Object数组存储,适用于频繁的查找工作,线程不安全。Vector是List的古老实现类,底层使用Object数组存储,线程安全的。

jdk7和jdk8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组,在扩容方面,默认扩容为原来数组长度的2倍。

12.如何实现数组和 List 之间的转换?

List转成为数组,调用ArrayList.toArray()方法,数组转化为list,调用Arrays.asList()方法。

13. 哪些集合类是线程安全的?

Vector HashTable ConcurrentHashMap Stack

14.在 Queue 中 poll()和 remove()有什么区别?

Queue中,add方法和offer方法都可以添加元素,而remove和poll都是删除队列的头元素,区别在于:
add方法在队列满的情况下抛异常,而offer方法则返回false.
remove方法在队列为空时抛异常,poll方法将返回null.

15.迭代器 Iterator 是什么?

Iterator是个接口,它提供了很多对元素进行迭代的方法.迭代器可以在迭代过程中删除底层集合的元素,可以直接调用Iterator的remove()方法来删除. 因为在Conllection接口中定义了获取集合迭代器的方法,所以每一个集合都包括了可以返回迭代器实例的方法.

16.Iterator 怎么使用?有什么特点?

每个集合都可以用iterator()方法一个Iterator实例.
使用next()方法获取序列中的下一个元素,使用hasNext()方法检查序列中是否有元素
使用remove()方法将迭代器新返回的方法删除.
特点:Iterator将集合的遍历和其底层的结构分离.

17. Iterator 和 ListIterator 有什么区别?

ListIterator是Iterator的子接口,用于扩展Iterator.
在Iterator中,我们只能向前移动,无法操纵或者修改集合中的元素.ListIterator弥补了这种缺点
区别: 1.范围不同,Iterator适用于所有集合,而ListIterator只适用于List及其子类
2.ListIterator有add方法可以添加元素,Iterator则不行.
3.ListIterator可以实现双向遍历,Iterator则不行.
4.ListIterator可以实现对象的修改,Iterator不行
5.ListIterator可以获取集合中的所有,Iterator不行.

18.比较HashSet、LinkedHashSet、TreeSet三者的异同?

HashSet是Set接口的主要实现类,HashSet的底层是HashMap,是线程不安全的,LinkedHashSet是HashSet的子类,能够按照添加顺序进行遍历,TreeSet底层使用红黑树,能够按照添加对象的指定属性进行排序,排序的方式有自然排序和定制排序。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值