一.集合
1.HashMap的低层实现原理?
线程不安全,存储null的key和value
jdk7:数组+链表(jdk7) HashMap map = new HashMap();在实例化之后就创建了一个长度为16的一维数组Entry[] table,map.put(key1,value1) 首先调用Key1所在类的hashCode()计算key1的哈希值,此哈希值经过某种算法计算后,得到在Entry数组存放的位置,如果此位置上的数据为空,此时的key1-value1添加成功,如果此位置上的数据不为空(意味着此位置上存在一个或多个数据(以链表的形式存在),比较key1值和已经存在的一个或者多个数据的哈希值:
如果Key1的哈希值和已经存在的哈希值都不相同,此时的key1-value1添加成功
如果key1的哈希值和已经存在的某一个数据的的哈希值相同,继续比较:调用key1所在类的equal()方法,比较:
如果equal()返回的false:此时的key1-value1添加成功
如果equal()返回的是true:则用value1替换value2值。
扩容为原来容量的两倍,并将原有的数据复制过来
jdk:数组+链表+红黑树(jdk8)
jdk8相较于jdk7在底层实现方面的不同:
-
new HashMap():底层没有创建一个长度为16的数组
2.jdk8底层的数组是:Node[],而非Entry[]
3.首次调用put()方法时,底层创建长度为16的数组
4.jdk7底层结构只有:数组+链表。jdk8中底层结构:数组+链表+红黑树。
当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时此索引位置上的所有数据改为使用红黑树存储。
2.ArrayList和linkedlist的区别?ArrayList是否会越界?
越界问题:当我们调用arraylist.add(object temp)的时候是不会出现数组越界的问题的,但是我们调用arraylist.add(int index, object temp)的时候,就有可能出现数组越界。如果我们初始化arraylist后,没有add元素就要按照索引插入元素,那么此时就会爆出数组越界的问题。因为此时arraylist还没有给你索引的地方分配空间。
3.string,stringbuilder,stringbuffer区别?/String. StringBuffer. StringBuilder三者的异同?
String:底层是一个final类型的字符数组,所以String的值是不可变的,每次对String的操作都会生成新的String对象,造成内存浪费,不可变的字符序列底层使用char[]存储。
StringBuffer:可变的字符序列线程安全的,效率低;底层使用char[]存储。
StringBuilder:可变的字符序列;jdk5.日新增的,线程不安全的,效率高;底层使用char[]存储。
4.抽象类和接口的区别?
抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法; 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的; 接口中不能含有静态代码块以及静态方法和构造方法,而抽象类可以有静态代码块和静态方法还有构造方法; 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
5.super关键字?this关键字?
super的使用,调用属性和方法
3.1我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用
父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super."
3.2特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的
使用"super.属性"的方式,表明调用的是父类中声明的属性。
3.3特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法。
4.super调用构造器
4.1我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器
4.2 "super(形参列表)"的使用,必须声明在子类构造器的首行!
this关键字的使用:
1.this可以用来修饰、调用:属性、方法、构造器工
2.this修饰属性和方法:
this理解为:当前对象或当前正在创建的对象
2.1在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。但是通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
2.2在类的构造器中,我们可以使用"this.属性"或"this.方法"的方式,调用当前正在创建的对象属性或但是,通常情况下,我们都选择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显的使用"this.变量"的方式,表明此变量是属性,而非形参。