数组与集合的区别?

  1. 数组是固定大小,集合是动态
  2. 数组的数据类型是基本数据类型或者对象,集合数据类型是对象
  3. 数组访问可以直接访问,集合需要迭代器

讲一下java有哪些集合?

集合分为collection集合和map集,collection集合分为list,set和queue,map集合是键值对。

list集合:ArrayList:基于数组,查询快,增删慢,LinkedList:基于双向链表,增删快,查询慢,Vector:类似arraylist,线程安全,开销大,copyonwriteList:线程安全的集合

set集合:HashSet:基于hash表,无序,不重复,LinkedHashSet:基于链表,hash表,有序,不重复,TreeSet:基于红黑树,有序,不重复

queue集合:LinkedList:作为队列使用,先进先出

map集合:HashMap:基于hash表,键值对无序,键不重复,允许一个键为null,LinkedHashMap:基于链表和hash表,有序,TreeMap:基于红黑树,键值对有序,键不重复,HashTable:线程安全,不允许键值为null,ConcurrentHashMap:基于hash表,线程安全,适合高并发,不允许键值为null

collections和collection的区别?

collection是集合框架接口,collections是一个工具包,位于java.utils下面

集合遍历的方式有哪些?

普通for循环,增强for循环,迭代器,foreach循环,stream流

讲一下list集合的实现?

  1. vecotor早期的线程安全的动态数组
  2. ArrayList线程不安全的动态数组,应用较多,尾部插入,适合查询
  3. LinkedList线程不安全的动态数组,基于链表,中间插入,适合增删

ArrayList和LinkedList集合的区别?

  1. 两个都不是线程安全的集合
  2. arraylist基于数组,尾部插入,中间插入开销大,需要元素后移,适合查询
  3. linkedlist基于链表,中间插入,适合增删

ArrayList的安全吗?变成安全的方法?

arraylist线程不安全,安全方法用CopyOnWriteArrayList替代

不安全原因:值为null,索引越界。

ArrayList的扩容机制?

初始容量为10,超过容器容量会创建1.5倍的数组,把原来的数组内容复制新数组,复制完成原来数组索引指向新的数组。

1
2
3
4
5
6
7
8
9
10
11
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}

CopyonWriteArraylist是怎么实现线程安全?

  1. 通过volatile保证数组被修改所有线程可以看见
  2. 在写入操作时,加了一把互斥锁ReentrantLock以保证线程安全,只能有一个线程修改

说一下hashmap的原理?

概念:

hashmap是键值对形式。

hash函数:将键映射在数组的具体位置

桶:数组里面的每个位置是桶

工作原理:当向 HashMap 插入一个键值对时,首先通过调用键对象的 hashCode() 方法计算出该键的哈希码。然后根据哈希码与数组长度取模运算得到桶的位置(即索引),由于不同的键可能产生相同的哈希码,或者即使哈希码不同但经过取模后也可能落入同一个桶中,这种情况被称为哈希冲突,这时候用链表和红黑树规范每个桶元素。

HashMap基于hash表,jdk1.7数据结构是基于数组和链表,jkd8以后链表长度超过8会转成数组+链表+红黑树

往map集合put元素的时候,键通过hashcode的到hash码,hash很长,通过取模得到桶的位置,把键和值放入桶里面,jdk1.7是创建entry,jdk1.8是node对象存储桶里面,hash冲突时候,桶里面元素链表存储,默认容量为16,负载因子0.75,超过12个(元素不是桶)触发扩容,链表是8个,如果链表到达8个而且数组达到64个,链表会转变为红黑树。如果链表到达8个,数组没有到达64个,会扩容不会变成红黑树

hashmap是线程安全的吗?

不安全,如果需要安全用ConcurrentHashMap

说一下hashmap的put过程?

键通过hashcode计算,然后取模得到桶位置,如果桶位置一样,同一个桶链表存储,链表长度为8,超过发生扩容,如果数组长度超过64,链表转为红黑树。

哈希map调用get方法安全吗?

不安全,多线程情况下一个get,一个修改,最后得到的结果不一样。

Hashmap一般用什么作为key?

String作为key,因为String对象是不可变的。

hashmap的key和value可以为null吗?

可以,null的键只能有一个,null的值可以有多个。

hashmap在多线程可能会出现哪些问题?

多线程里面多个线程put数据,计算索引一致,会造成前一个key被后一个key覆盖,数据丢失。

说一下hashmap的扩容机制?

默认负载因子是0.75,当元素超过容量的75%会发生扩容。

HashMap和HashTable有什么不一样?

一个线程安全一个线程不安全。

ConcurrentHashMap是怎么实现的?

对桶加锁的

hashtable的底层原理?

get和put是通过同步方法加锁,同一时刻只有一个线程操作。

Hashtable是通过使用了 synchronized 关键字来保证其线程安全

set集合的特点?

元素唯一不重复

实现原理:通过hashcode确定元素的位置,通过equals判断是否存在相同的元素,如果存在不会插入。

哪些set集合是有序的?

treeSet和LinkedHashSet