1.谈谈你对ArrayList的理解
ArrayList实现了List接口,底层采用的数组实现。
ArrayList实现了Cloneable接口,即覆盖了clone()方法,能被克隆。
ArrayList实现了java.io.Serializable接口,这意味着ArrayList支持序列化,能够通过序列化传输。
构造函数
ArrayList提供了三个构造函数:
ArrayList():默认构造函数,提供初始容量为10的空列表。
ArrayList(int initialCapacity):构造一个具有指定初始容量的空列表。
ArrayList(Collection<? extends E> c):构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
扩充算法:新容量 = 原容量 + 原容量>>1 (即原容量的1.5倍)
2.ArrayList和LinkedList的区别
- ArrayList 是一个array(动态数组)的数据结构,LinkedList是一个link(链表)的数据接口,两者都实现了List接口,前者是对数组队列,后者是双向链表结构。
- 当执行get和set操作时,ArrayLIst要比LinkedList操作效率要高,因为LinkedList是线性存储结构,所以需要移动指针从前往后查找。
- 当对数据执行增加和删除操作时,LinkedList的要比ArrayList的操作效率要高,因为ArrayList是数组,对数据进行增删操作时,会对操作之后的所有数据的下标点索引造成影响,需要进行数据的移动。
- ArrayList的空间开销主要在于为List预留一定的空间,LinkedList的空间开销主要在于存储节点信息和节点指针信息。
3.浅谈对hashMap的理解
- HashMap是一个散列表(对象数组+链表),它存储的内容是键值对(key-value)映射。
- HashMap的实现是不同步的,这意味的它是线程不安全的,它的key和value都可以为null(key唯一),此外,HashMap的映射不是有序的。
- HashMap的初始容量为16,默认加载因子为0.75
- hashMap存储数据的算法:根据key的hash值取余数组的大小,获取的值是数组大小的之间的值(0-15),这个值决定了value要存储在哪个链表中,在根据equlas方法判断key是否重读,如果重复则覆盖value(即key唯一)。
- 数组扩容算法:当数组容量中75%(加载因子)有元素时,就对数组扩容(原容量的2倍),然后重新散列(rehash),因为数组长度发生变化,以前存储的值位置要全部发生改变。
4.浅谈对TreeMap的理解
- TreeMap基于平衡二叉树实现(红黑树)
- TreeMap是有序的,排序规则有两种,分别为
默认排序规则:按照key的字典顺序来排序(升序)
自定义排序规则:实现Comparator接口。
5.HashMap和Hashtable的区别
HashMap和Hashtable都实现了Map接口,并且都是key-value的数据结构。它们的不同点主要在三个方面:
第一,Hashtable是Java1.1的一个类,它基于陈旧的Dictionary类。而HashMap是Java1.2引进的Map接口的一个实现。
第二,Hashtable是线程安全的,也就是说是线程同步的,而HashMap是线程不安全的。也就是说在单线程环境下应该用HashMap,这样效率更高。
第三,HashMap允许将null值作为key或value,但Hashtable不允许(会抛出NullPointerException)。
6.ArrayList和Vector的区别
ArrayList和Vector都实现了List接口,他们都是有序集合,并且存放的元素是允许重复的。它们的底层都是通过数组来实现的,因此列表这种数据结构检索数据速度快,但增删改速度慢。
而ArrayList和Vector的区别主要在两个方面:
第一,线程安全。Vector是线程安全的,而ArrayList是线程不安全的。因此在如果集合数据只有单线程访问,那么使用ArrayList可以提高效率。而如果有多线程访问你的集合数据,那么就必须要用Vector,因为要保证数据安全。
第二,数据增长。ArrayList和Vector都有一个初始的容量大小,当存储进它们里面的元素超过了容量时,就需要增加它们的存储容量。ArrayList每次增长原来的0.5倍,而Vector增长原来的一倍。ArrayList和Vector都可以设置初始空间的大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。