java面试题整理《集合篇》二

Arraylist 与 LinkedList 区别?
底层数据结构: Arraylist 底层使⽤的是 Object 数组; LinkedList 底层使⽤的是双向链表数据结构(JDK1.6 之前为循环链表,JDK1.7 取消了循环。)
是否保证线程安全: ArrayList 和 LinkedList 都是不同步的,不保证线程安全;
插⼊和删除是否受元素位置的影响:
① ArrayList 采⽤数组存储,所以插⼊和删除元素的时间复杂度受元素位置的影响。 执⾏ add(E e) ⽅法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是 O(1),但是可能会产生扩容。但是如果要在指定位置 i插⼊和删除元素的话时间复杂度就为 O(n-i)。因为在进⾏上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执⾏向后位/向前移⼀位的操作。
②LinkedList 采⽤链表存储,所以对于 add(E e) ⽅法的插⼊,删除元素时间复杂度不受元素位置的影响,近似 O(1),如果是要在指定位置 i 插⼊和删除元素的话时间复杂度近似为 O(n) 因为需要先移动到指定位置再插⼊。
随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。
内存空间占⽤:LinkedList 的每一个节点要比 ArrayList 更占内存,因为 LinkedList 的节点除了存储数据,还存储了前后引用。而 ArrayList 的空间浪费主要体现在在 list 列表的结尾会预留⼀定的容量空间。
在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用 LinkedList。

ArrayList的扩容机制:
以无参数构造方法创建 ArrayList 时,实际上初始化赋值的是一个空数组。当真正对数组进行添加元素操作时,才真正分配容量。即向数组中添加第一个元素时,数组容量扩为 10。 之后在进行扩容时,每次扩容为原来的 1.5 倍。

多线程场景下如何使用 ArrayList?
ArrayList 不是线程安全的,如果遇到多线程场景,可以通过 Collections 的 synchronizedList 方法将其转换成线程安全的容器后再使用。例如像下面这样:

  1. 
    List<String> synchronizedList = Collections.synchronizedList(list); 
     
    synchronizedList.add("aaa"); 
     
    synchronizedList.add("bbb"); 
     
    for (int i = 0; i < synchronizedList.size(); i++) { 
        System.out.println(synchronizedList.get(i)); 
    }
    
    


也可以使用线程安全的CopyOnWriteArrayList,其底层也是对增删改方法进行加锁:final ReentrantLock lock = this.lock;

HashMap 和 Hashtable 有什么区别?
线程是否安全:HashMap是线程不安全的,HashTable是线程安全的(内部的⽅法基本都经过 synchronized 修饰);
效率: 因为线程安全的问题, HashMap 要⽐ HashTable 效率⾼⼀点
是否支持键值为null:HashMap中允许键和值为null,但是null作为键只能有一个,HashTable不支持;
扩容机制:HashMap的默认容器是16,为2倍扩容,HashTable默认是11,为2倍+1扩容;
底层数据结构: JDK1.8 以后的 HashMap 当链表⻓度⼤于阈值(默认为 8)(将链表转换成红⿊树前会判断,如果当前数组的⻓度⼩于 64,那么会选择先进⾏数组扩容,⽽不是转换为红⿊树)时,将链表转化为红⿊树,以减少搜索时间。Hashtable 没有这样的机制。
https://www.bilibili.com/video/BV1qL411u7eEicon-default.png?t=M666https://www.bilibili.com/video/BV1qL411u7eE

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值