1.1 list是有序集合(容器)且元素能够重复,输出顺序就是插入顺序;Set是无序集合且元素不能够重复。
1.2 list能够存放多个null;set只能够存一个null
1.3 经常使用list有ArrayList,LinkedList,vector;
- 优势:ArrayList是实现了基于动态数组的数据结构,由于地址连续,一旦数据存储好了,查询操做效率会比较高(在内存里是连着放的)。
- 缺点:由于地址连续, ArrayList要移动数据,因此插入和删除操做效率比较低。
- 优势:LinkedList基于链表的数据结构,地址是任意的,因此在开辟内存空间的时候不须要等一个连续的地址,对于新增和删除操做add和remove,LinedList比较占优点。LinkedList 适用于要头尾操做或插入指定位置的场景
- 缺点:由于LinkedList要移动指针,因此查询操做性能比较低。
- 当须要对数据进行对此访问的状况下选用ArrayList,当须要对数据进行屡次增长删除修改时采用LinkedList。
- ArrayList和Vector都是用数组实现的,主要有这么三个区别:
- 1.Vector是多线程安全的,线程安全就是说多线程访问同一代码,不会产生不肯定的结果。而ArrayList不是,这个能够从源码中看出,Vector类中的方法不少有synchronized进行修饰,这样就致使了Vector在效率上没法与ArrayList相比;
- 2.两个都是采用的线性连续空间存储元素,可是当空间不足的时候,两个类的增长方式是不一样。
- 3.Vector能够设置增加因子,而ArrayList不能够。
- 4.Vector是一种老的动态数组,是线程同步的,效率很低,通常不同意使用。
- 经常使用的set有HashSet,LinkedSet,Treeset,[简单介绍]
- .HashSet 是哈希表实现的,HashSet中的数据是无序的,能够放入null,但只能放入一个null,二者中的值都不能重复,就如数据库中惟一约束
- HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码做为标识的,而具备相同内容的String对象,hashcode是同样,因此放入的内容不能重复。可是同一个类的对象能够放入不一样的实例
- 适用场景分析:HashSet是基于Hash算法实现的,其性能一般都优于TreeSet。为快速查找而设计的Set,咱们一般都应该使用HashSet,在咱们须要排序的功能时,咱们才使用TreeSet。
- TreeSet 是二差树(红黑树的树据结构)实现的,Treeset中的数据是自动排好序的,不容许放入null值
1.4 [应用场景]
1.若是你常常会使用索引来对容器中的元素进行访问,那么 List 是你的正确的选择。若是你已经知道索引了的话,那么 List 的实现类好比 ArrayList 能够提供更快速的访问,若是常常添加删除元素的,那么确定要选择LinkedList。
2.若是你想容器中的元素可以按照它们插入的次序进行有序存储,那么仍是 List,由于 List 是一个有序容器,它按照插入顺序进行存储。
3.若是你想保证插入元素的惟一性,也就是你不想有重复值的出现,那么能够选择一个 Set 的实现类,好比 HashSet、LinkedHashSet 或者 TreeSet。全部 Set 的实现类都遵循了统一约束好比惟一性,并且还提供了额外的特性好比 TreeSet 仍是一个 SortedSet,全部存储于 TreeSet 中的元素可使用 Java 里的 Comparator 或者 Comparable 进行排序。LinkedHashSet 也按照元素的插入顺序对它们进行存储。
4.若是你以键和值的形式进行数据存储那么 Map 是你正确的选择。你能够根据你的后续须要从 Hashtable、HashMap、TreeMap 中进行选择。
注意:
LinkedList、ArrayList、HashSet是非线程安全的,Vector是线程安全的;
HashMap是非线程安全的,HashTable是线程安全的;
StringBuilder是非线程安全的,StringBuffer是线程安全的。
扩展:
HashMap 非线程安全
HashMap:基于哈希表实现。使用HashMap要求添加的键类明肯定义了hashCode()和equals()[能够重写hashCode()和equals()],为了优化HashMap空间的使用,您能够调优初始容量和负载因子。
TreeMap:非线程安全基于红黑树实现。TreeMap没有调优选项,由于该树总处于平衡状态。
适用场景分析:
HashMap和HashTable:HashMap去掉了HashTable的contains方法,可是加上了containsValue()和containsKey()方法。HashTable同步的,而HashMap是非同步的,效率上比HashTable要高。HashMap容许空键值,而HashTable不容许。
HashMap:适用于Map中插入、删除和定位元素。
Treemap:适用于按天然顺序或自定义顺序遍历键(key)。
- HashSet 是如何保证不重复的
1.hashset是基于哈希表实现的,先要根据hash码值(就是key的hashcode值)去判断,而后在用equals判断,都相等为已有元素,不在存储。不然做为新元素存存储。html
三、HashMap 是线程安全的吗,为何不是线程安全的(最好画图说明多线程环境下不安全)?
1.不是线程安全的,因为hash碰撞,以及扩容致使
**经过Entry内部的next变量能够知道使用的是链表,这时候咱们能够知道,若是多个线程,在某一时刻同时操做HashMap并执行put操做,而有大于两个key的hash值相同,
如图中a一、a2,这个时候须要解决碰撞冲突,而解决冲突的办法上面已经说过,对于链表的结构在这里再也不赘述,暂且不讨论是从链表头部插入仍是从尾部初入,
这个时候两个线程若是刚好都取到了对应位置的头结点e1,而最终的结果可想而知,a一、a2两个数据中势必会有一个会丢失
**多个线程同时检测到总数量超过门限值的时候就会同时调用resize操做,各自生成新的数组并rehash后赋给该map底层的数组table,java
结果最终只有最后一个线程生成的新数组被赋给table变量,其余线程的均会丢失。并且当某些线程已经完成赋值而其余线程刚开始的时候,就会用已经被赋值的table做为原始数组,这样也会有问题node
**(仍是解释扩容致使线程不安全问题)若是多个线程同时检测到元素个数超过数组大小*loadFactor,这样就会发生多个线程同时对Node数组进行扩容,都在从新计算元素位置以及复制数据,可是最终只有一个线程扩容后的数组会赋给table,也就是说其余线程的都会丢失,而且各自线程put的数据也丢失算法
四、HashMap 的扩容过程
参考:https://blog.csdn.net/aichuanwendang/article/details/53317351
https://www.cnblogs.com/KingIceMou/p/6976574.html
1.数组的长度2的32幂,hashmap初始大小为16,负载因子默认我0.75
2.hashmap是懒加载,构造完HashMap对象后,只要不进行put 方法插入元素以前,HashMap并不会去初始化或者扩容table:
3.插入数据时,会去判断hashmap的哈希表长度*负载因子,若是这个值小于hashmap中当前元素的个数,就会去调用resize方法去扩容。
参考:https://www.cnblogs.com/kuoAT/p/6771653.html
arraylist动态扩容,初始大小为10或者0(无参构造器),以1.5倍大小扩容,调用grow方法。
五、HashMap 1.7 与 1.8 的 区别,说明 1.8 作了哪些优化,如何优化的?
https://www.cnblogs.com/stevenczp/p/7028071.html
1.使用node数组存数据,对key作哈希获得的hashcode后,若是hashcode重复,会放到链表中,若是超过8个把链表转化为红黑树,这样查找会快点
2.要实现Compare接口,若是不实现尚未1.7的快
hashmap实现compare接口
https://blog.csdn.net/zly9923218/article/details/51656920
六、final finally finalize
1.final是修饰符,能够修复类,方法,属性;
2.被final修饰的类不能被继承;被final修饰的方法只能使用,不能被重载;被final修饰的变量就是常量了,必须有初始值,不能拿被修改。
finally 是处理异常时来执行清除操做,无论有没有抛出,捕获,finally块最后都会被执行。
finalize 在垃圾回收器将对象从内存中清除出去以前作必要的清理工做。
七、强引用 、软引用、 弱引用、虚引用
强引用是使用最广泛的引用:Object o=new Object(); 特色:不会被GC数据库
软引用用来描述一些还有用可是并不是必须的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。
所以,这一点能够很好地用来解决OOM的问题,而且这个特性很适合用来实现缓存:好比网页缓存、图片缓存等数组
弱引用与软引用的区别在于:只具备弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程当中,
一旦发现了只具备弱引用的对象,无论当前内存空间足够与否,都会回收它的内存。不过,因为垃圾回收器是一个优先级很低的线程,
所以不必定会很快发现那些只具备弱引用的对象缓存
虚引用也称为幻影引用:一个对象是都有虚引用的存在都不会对生存时间都构成影响,也没法经过虚引用来获取对一个对象的真实引用。
惟一的用处:能在对象被GC时收到系统通知,JAVA中用PhantomReference来实现虚引用。安全
八、Java反射
九、Arrays.sort 实现原理和 Collection 实现原理
十、LinkedHashMap的应用
1.须要保证插入顺序的
十一、cloneable接口实现原理
十二、异常分类以及处理机制
1三、wait和sleep的区别
1四、数组在内存中如何分配
参考:
https://blog.csdn.net/qq_22118507/article/details/51576319
*************************************************
一:List接口
1.List集合表明一个有序集合,集合中每一个元素都有其对应的顺序索引。List集合容许使用重复元素,能够经过索引来访问指定位置的集合元素
ArrayList:
1.ArrayList是一个动态数组,也是咱们最经常使用的集合,初始容量(10),该容量表明了数组的大小。随着容器中的元素不断增长,容器的大小也会随着增长
2.ArrayList擅长于随机访问。同时ArrayList是非同步的
LinkedList
1.LinkedList是一个双向链表,除了有ArrayList的基本操做方法外还额外提供了get,remove,insert方法在LinkedList的首部或尾部
2.LinkedList不能随机访问,LinkedList也是非同步的
Vector
1. 与ArrayList类似,可是Vector是同步的。因此说Vector是线程安全的动态数组。它的操做与ArrayList几乎同样。
Stack
1.Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被看成堆栈使用。基本的push和pop 方法,还有peek方法获得栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚建立后是空栈。
二:Set接口
1.Set是一种不包括重复元素的Collection,Set接口有三个具体实现类,分别是散列集HashSet、链式散列集LinkedHashSet和树形集TreeSet。
HashSet
1.HashSet 是一个没有重复元素的集合。它是由HashMap实现的,不保证元素的顺序;HashSet是非同步的
2.HashSet的实现方式大体以下,经过一个HashMap存储元素,元素是存放在HashMap的Key中,而Value统一使用一个Object对象
LinkedHashSet
1. LinkedHashSet继承自HashSet,有序,非同步。
TreeSet
1.TreeSet是一个有序集合,其底层是基于TreeMap实现的,非线程安全
三:Map接口
HashMap
1.以哈希表数据结构实现,查找对象时经过哈希函数计算其位置,它是为快速查询而设计的,其内部定义了一个hash表数组(Entry[] table),元素会经过哈希转换函数将元素的哈希地址转换成数组中存放的索引,若是有冲突,则使用散列链表的形式将全部相同哈希地址的元素串起来,可能经过查看HashMap.Entry的源码它是一个单链表结构。
LinkedHashMap
1.
TreeMap
1.TreeMap 是一个有序的key-value集合,非同步,基于红黑树(Red-Black tree)实现,每个key-value节点做为红黑树的一个节点。TreeMap存储时会进行排序的,会根据key来对key-value键值对进行排序,其中排序方式也是分为两种,一种是天然排序,一种是定制排序,具体取决于使用的构造方法
参考:
https://www.cnblogs.com/xiaoxi/p/6089984.html