一.java基础:
1.集合分为:Collection(单列集合)和Map(双列集合);
1>List单列集合,有序,可重复;
ArryList:底层是一个数组,通过在类中定义一个变量名为elementData的Object数组和size大小,size初始值为0,存储的时候size++ 根据索引进行有序存储,但是没有对存储做判断,这就是有序可重复的原因;当我们创建对象的时候,集合的初始容量为0,第一次调用add方法的时候,会给一个初始容量为10,也就是实现了懒加载;elementData的Object数组;
ArrayList扩容时机:一般是存满扩容,底层调用grow方法的时候有个判断,当元素的数量大于数组的长度,就会触发grow方法,扩容为原来的1.5倍,注意底层是int类型数据,如果有半数啥的,就舍去余数;
为什么ArrayList的查询速度快,增删速度慢?底层是数组嘛,有索引,所以查询的效率是 O(1),但是增删需要重排索引 效率是O(n),但是我认为也不绝对,当我们顺序增删的时候,效率依旧很快...
遍历方式:增强 for,迭代器,stream 流,普通 for =>函数式编程;
不安全集合: 迭代器:底层存在两个方法,hasnext()负责判断是否有下个元素,返回true,next()是获取到元素,并且指针下移;
但是在新增大量的数据时ArryList比LinkList的效率要高些,因为ArryList的扩容是按照1.5倍扩容新增快;
LinkList:底层是一个双向链表,它的每一个结点是由Node对象构成的。 这个Node对象主要存储了3个信息,链表中指向的上一个结点对象,当前结点所要存储的数据以及链表中指向的下一个结点对象。也可以理解为指向前结点的指针、存储数据以及指向后结点的指针。 增删效率高,只需要断开头尾的指针,效率是O(1),查询效率比较低是O(n)....;
2>.Set单列集合,无序,不可重复
HashSet:HashSet是基于HashMap实现的,它底层的HashMap里面的Key就是HashSet中需要存储的对象,他的Value是一个常量Object对象。
TreeSet:TreeSet是一种不重复元素之间可以进行排序的单列集合,我们可以通过让要放入TreeSet中的泛型对象实现Comparable接口中的compareTo方法,实现自然排序。也可以在使用构造器创建TreeSet对象时,传入一个Comparator比较器对象,重写比较器中的compare方法,来实现比较器排序。
3>Map:是双列集合的顶级父接口,他的存储形式是以Key:value键值对的形式进行存储的。它的常见实现类有HashMap、LinkedHashMap以及TreeMap。
HashMap:双列集合,实现了map接口,存在K和V就是键和值,储存的特点是K键唯一,V值随便...并且是无序的...首次put的时候会初始化数组长度16,阈值是0.75...
jdk1.7: 1.底层原理是哈希表,数组+链表的结构 entry数组+单向链表 初始容量是0, 存储是通过hash值和数组长度计算出来的哈希值,所以无序,,当你的K相同 ,会用新的value替换老的value... 2.put方法执行: 当你首次put的时候 默认长度是16....底层规定数组的长度一定是2的幂次方..... 3.扩容机制:满足两个条件,计算元素的size大于等于阈值(数组容量*加载因子 默认是16 乘0.75 =12),并且引起哈希冲突才会扩容,扩容为原来长度的两倍....哈希冲突就是数组下链表的下标不为null,在扩容时会采用头插法,在单线程时表现正常,但在多线程时存在着链表循环的问题。
jdk1.8的改良: 1.结构上 :数组+链表+红黑树,可以提高查询的效率 2.哈希冲突后存储的方式,头插法改成尾插法,减少环链的问题,但没法解决 3.扩容机制,当存储的元素大于阈值,必定扩容 ,还有数组的长度<64的时候,链表长度大于8,也会扩容;并且采用了尾插法,可以尽量避免链表的循环引用。
并发场景下: hashMap是线程不安全的集合,可以用JUC包下的ConcurrentHashMap...这个我也有点了解 这个集合1.7和1.8也有些不同,我看过一些博客是讲1.7是segment+数组+链表 ,segment做锁,多个线程访问不同的segment则不会冲突,原理是用分段锁segment,jdk1.8后是 数组+链表+红黑树,以头节点做锁,数组的容量决定并发量....底层原理是用悲观锁+乐观锁实现的。
为什么引入红黑树?解决链表过长查询效率低下的问题,提升查询,但是短链表的效率不一定比红黑树效率低,并且红黑树的存储空间大于链表结构...红黑树的转化阈值是8 ? 计算得到 链表大于8的概率极低有千万分之一,所以设置这个阈值... 链表的转化阈值是6
为什么初始容量是16? 2的幂次方在位运算的情况下速度最快;
为什么加载因子是0.75?是对空间占用和对查询时间做较好的权衡,大于0.75拿时间换空间,小于0.75是拿空间换时间;
什么是hash冲突? 两个不同元素通过hash运算,得到的角标相同,四种方案:重hash,开发地址,建立公共移除,链地址.
LinkedHashMap:继承于HashMap,基于HashMap和双向链表来实现的。使用LinkedList主要是为了维护插入顺序,LinkedHashMap是线程不安全的。
TreeMap:底层是红黑树结构,存储特点是:无序和不可重复,并且元素是按照你定义的排序规则进行排序...依赖自然排序或者比较器排序,对键进行排序 如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器排序规则;
2.== 和 equals区别:
== 比较基本类型的数据比较的是 值是否相等,比较引用类型是比较内存地址是否相等;
equals 一般都是重写了 Object的equals 的方法来对两个对象的内容进行比较,如果不重写的话,底层就是 == 比较的就是内存地址,equals 不能用于基本类型的比较。
3.final 在 java中有什么作用?
final 修饰基本类型为常量,是不可被改变; final 修饰引用类型,数据本身可以被修改,但是地址的引用不能被修改;final 修饰成员变量必须赋值;final修饰方法,这个方法将成为最终方法,无法被子类重写,但是仍可以被继承;final修饰的类无法被继承;
4.普通类和抽象类有哪些区别?
抽象类不能被实例化;
抽象类可以有抽象方法,只需声明,无需实现;
有抽象方法的类一定是抽象类;<