-
List与set集合的区别
相同点:
1.都是collection接口的子接口
2.都是集合对象
不同点:
1.List集合是有序存储,Set集合是无序存储。这里的有序和无序针对的是存储地址来说的。
2.List可以存储重复的值,Set不可以存储重复的值.
-
集合框架体系图:
-
ArrayList的实现原理
1.ArrayList 参考地址:https://www.cnblogs.com/leesf456/p/5308358.html
1)数组结构
2)类的继承关系
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
说明:ArrayList继承AbstractList抽象父类,实现了List接口(规定了List的操作规范)、RandomAccess(可随机访问)、Cloneable(可拷贝)、Serializable(可序列化)。
3)ArrayList(int)构造函数
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) { // 初始容量大于0
this.elementData = new Object[initialCapacity]; // 初始化元素数组
} else if (initialCapacity == 0) { // 初始容量为0
this.elementData = EMPTY_ELEMENTDATA; // 为空对象数组
} else { // 初始容量小于0,抛出异常
throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
}
}
2. ArrayList()型构造函数
public ArrayList() {
// 无参构造函数,设置元素数组为空
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
说明:当未指定初始化大小时,会给elementData赋值为空集合。
说明:当传递的参数为集合类型时,会把集合类型转化为数组类型,并赋值给elementData。
说明:指定elementData数组的大小,不允许初始化大小小于0,否则抛出异常。
4)添加数据时
ArrayList是可变长度数组,数组扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量增长大约是其容量的1.5倍。
ArrayList:线程不安全,查询速度快,增删速度慢;
底层数据结构是数组结构
默认初始容量是10;
扩容增量:原容量的 0.5倍
如: ArrayList的容量为10,一次扩容后是容量为15
备注:获取容量的方法
public static int getCapacity(ArrayList arrayList) {
try {
Field elementDataField = ArrayList.class.getDeclaredField("elementData");
elementDataField.setAccessible(true);
return ((Object[]) elementDataField.get(arrayList)).length;
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
return -1;
}
}
-
ArrayList和LinkedList的区别
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
-
hashmap的原理
https://www.cnblogs.com/leesf456/p/5242233.html
说明:上图很形象的展示了HashMap的数据结构(数组+链表+红黑树),桶(bucket)中的结构可能是链表,也可能是红黑树,红黑树的引入是为了提高效率。
1)HashMap是基于哈希表的Map接口的非同步实现,允许使用null值和null键,但不保证映射的顺序。public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
2)底层使用数组实现,数组中每一项是个单向链表,即数组和链表的结合体;当链表长度大于一定阈值时,链表转换为红黑树,这样减少链表查询时间。
3)HashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Node对象。HashMap底层采用一个Node[]数组来保存所有的key-value对,当需要存储一个Node对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Node时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Node。
4)HashMap进行数组扩容需要重新计算扩容后每个元素在数组中的位置,很耗性能
HashMap:
默认初始容量为16
加载因子为0.75:即当HashMap中元素个数 超过数组长度的0.75倍 时,进行扩容
扩容增量:原容量的 1 倍
如 HashMap的容量为16,一次扩容后是容量为32
a.什么时候扩容
当向容器添加元素的时候,会判断当前容器的元素个数,如果大于等于阈值,即当前数组的长度乘以加载因子的值的时候,就要自动扩容啦。
b.什么时候树形化
执行树形化之前,会先检查数组长度,如果长度小于64,则对数组进行扩容,而不是进行树形化。
-
HashMap与HashTable的区别
hashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。
主要的区别有:线程安全性,同步(synchronization),以及速度。
1.HashMap可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行。
2.HashTable是线程安全的,ConcurrentHashMap是HashTable的替代,线程安全的。
3. 由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
-
HashSet的原理
1)底层结构
因为HashSet底层是基于HashMap 或者 LinkedHashMap实现的,所以HashSet数据结构就是HashMap或者LinkedHashMap的数据结构
2)默认容量是16,加载因子是0.75