聊聊java集合

聊聊java集合

1:java中有哪些集合

类型主要有三种list(有序、可重复),set(无序、不能重复),map(键值对,键唯一、值不唯一)

集合主要有:ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、TreeMap

2:ArrayList和LinkedList区别是啥?

ArrayList是实现了基于动态数组的数据接口,LinkedList是基于链表的数据结构。

对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。

LinkedList中的get方法是按照顺序从列表的一端开始检查,直到另外一端。为什么对于数组查询就快了???因为假设数组中保存了一组int类型的对象,int类型有是占了4个字节,若要找第9个对象,则(9-1)*4=32,从33到36字节就是我们要找的对象。
对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

数组的插入是相当的浪费效率,如果要在数组内的某一个位置进行插入,需要先将插入位置的前面复制一份,然后在新的数组后面添加新的元素,最后将旧的数组后半部分添加到新的数组后面。而在链表中插入就变得相当简单了,比如我要在A3和A4之间插入数据B,只需定位到A3的指针和A4的数据即可,将A3的指针指向B的值,将B的指针指向A4的值,B就插入进了链表。

ps :set对于ArrayList是替换数组中已经存在的元素内容,add是添加新的元素。

3:HashMap和ConcurrentHashMap实现原理?

HashMap采用 数组 + 链表 + 红黑树的存储结构(链表长度大于8以后,采用红黑树存储)

ConcurrentHashMap底层依旧是采用 数组 + 链表 + 红黑树的存储结构,java7是利用Segment分段锁机制,到java8是利用CAS + Synchronized来保证并发更新的安全,比如对Node类中的value和next属性设置了volatile同步锁。

4:HashMap和HashTable区别?

HashMap是非线程安全的,HashTable实现线程安全是通过关键字synchronized修饰每个方法来实现的

5:ArrayList和Vector的区别(为什么要用ArrayList取代Vector)?

Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。

当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。

6:HashSet如何检查重复?

HashSet是哈希表结构,当一个元素要存入HashSet集合时,首先通过自身的hashCode方法算出一个值,然后通过这个值查找元素在集合中的位置,如果该位置没有元素,那么就存入。如果该位置上有元素,那么继续调用该元素的equals方法进行比较,如果equals方法返回为真,证明这两个元素是相同元素,则不存。否则则在该位置上存储2个元素(一般不可能重复)所以当一个自定义的对象想正确存入HashSet集合,那么应该重写Object的hashCode和equals。HashSet是通过hashCode()和equals()方法确保元素无序不重复的

7:hashCode()和equals()方法作用?

1
2
3
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
1
2
3
4
5
6
7
8
9
10
11
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}

8:队列和栈的区别?

(1)操作的名称不同。队列的插入称为入队,队列的删除称为出队。栈的插入称为进栈,栈的删除称为出栈。

(2)可操作的方式不同。队列是在队尾入队,队头出队,即两边都可操作。而栈的进栈和出栈都是在栈顶进行的,无法对栈底直接进行操作。

(3)操作的方法不同。队列是先进先出(FIFO),即队列的修改是依先进先出的原则进行的。新来的成员总是加入队尾(不能从中间插入),每次离开的成员总是队列头上(不允许中途离队)。而栈为后进先出(LIFO),即每次删除(出栈)的总是当前栈中最新的元素,即最后插入(进栈)的元素,而最先插入的被放在栈的底部,要到最后才能删除。

9:说一个Queue的使用场景?

数据库连接池,消息队列

10:HashMap扩容规则?

HashMap默认使用的负载因子值为0.75f(当容量达到四分之三进行再散列(扩容)),超过最大值就不再扩容,未超过最大值,则扩容至原来的两倍,容量和临界值都翻倍