怒怼面试官-别再问我JAVA List了

了解JAVA的List吗?

List是一个接口,查关键的实现类有ArrayList和LinkedList

讲讲这两个实现类的区别?

  • ArrayList的底层数据结构是数组,支持下标访问,查询数据快,默认初始值为10,容量不足时会进行扩容。
  • 而LinkedList的顶层数据结构是链表,将元素添加到链表的末尾,无需扩容

ArrayList是怎么扩容的,详细讲讲?

arrayList扩容源码实现如下:

    private Object[] grow(int minCapacity) {
        return elementData = Arrays.copyOf(elementData,
                                           newCapacity(minCapacity));
    }

    private Object[] grow() {
        return grow(size + 1);
    }

    private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity <= 0) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
                return Math.max(DEFAULT_CAPACITY, minCapacity);
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return minCapacity;
        }
        return (newCapacity - MAX_ARRAY_SIZE <= 0)
            ? newCapacity
            : hugeCapacity(minCapacity);
    }

可以看到,在graw方法里面进行扩容,将数组容量扩大为原来的1.5倍。
举个例子,如果初始化的值是8,当添加第9个元素的时候,发现数组空间不够,就会进行扩容,扩容之后容量为12.
扩容之后,会调用Arrays.copyOf()方法对数组进行copy。

ArrayList和LinkedList分别应用于什么场景呢?

对于随机index访问的get和set方法,ArrayList的速度要优于LinkedList,因为ArrayList直接通过数组下标直接找到元素;LinkedList要移动指针遍历每一个元素直到找到为止。
新增和删除元素,LinkedList的速度要优于ArrayList,因为ArrayList在新增和删除元素的时候,可能会扩容和复制数组,而LinkedList的新增和删除操作只需要修改指针即可。
因为ArrayList适用于查询多,增删少的场景,而LinkedList适用与查询少,增删多的场景

讲讲Set和List的区别?

List以索引来存取元素,有序的,元素是允许重复的,可以插入多个null值,Set不能存放重复元素,无序的,只允许插入一个null。
List底层实现有数组,链表两种方式,Set基于Map实现,Set里的元素值就是Map的键值。

了解Vector吗?

Vector的底层结构是数组,现在基本没有使用Vector了,因为操作Vector效率比较低,相对于ArrayList,它是线程安全的,在扩容的时候容量扩展为原来的2倍。

那你还知道哪些线程安全的List?

可以使用Collections.synchronizedList()方法返回一个线程安全的List。
还有另外一种方法,使用CopyOnWriteArrayList。

讲一下CopyOnWriteArrayList原理?

CopyOnWriteArrayList是一个线程安全的List,底层是通过复制数组的方式来实现的。
所谓的CopyOnWrite,就是写时复制。
当我们往容器添加元素时,不直接往容器添加,而是先将当前容器进行复制,复制出一个新的容器,然后往新的容器添加元素,添加完元素之后,再将原容器引入指向新容器。
这样做的好处就是可以对CopyOnWrite容器进行并发的读而不需要加锁,因为当前容器不会被修改。

那你说说CopyOnWriteArrayList有什么缺点吗?

主要有以下俩个问题:

  • 内存占用问题,由于CopyOnWrite的写时复制机制,在进行写操作时,内存里会有两个对象的内存。
  • CopyOnWrite容器不能保证数据的实时一致性,可能读取到旧数据。

怎么给List排序呢?

可以使用List自身的sort方法,或者使用Collections.sort(list)方法。

怎么在遍历ArrayList时移除一个元素?

如果使用foreach删除元素的话,会导致快速失败问题,可以使用迭代器的remove方法,避免快速失败问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初级程序员s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值