JavaSE
一、Java基础
Java基础部分(基本语法、Java特性等)
1 为什么重写equals还要重写hashcode
因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,所以我们可以得出:
1.equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
2.hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
所有对于需要大量并且快速的对比的话如果都用equal()去做显然效率太低,所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equal()去再对比了),如果hashCode()相同,此时再对比他们的equal(),如果equal()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性。
然而hashCode()和equal()一样都是基本类Object里的方法,而和equal()一样,Object里hashCode()里面只是返回当前对象的地址,如果是这样的话,那么我们相同的一个类,new两个对象,由于他们在内存里的地址不同,则他们的hashCode()不同,所以这显然不是我们想要的,所以我们必须重写我们类的hashCode()方法,即一个类,在hashCode()里面返回唯一的一个hash值。
2 说一下map的分类和常见的情况
类名:java.util.Map,包含4个实现类:HashMap、Hashtable、LinkedHashMap、TreeMap
类名 | 是否允许键或值为null | 是否线程安全 | 是否有序 |
---|---|---|---|
HashMap | 是 | 否 | 否 |
Hashtable | 否 | 是 | 否 |
LinkedHashMap | 是 | 否 | 是 |
TreeMap | 否 | 否 | 是 |
- HashMap是最常用的Map,它根据键的hashcode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap仅允许一条记录的键为null,允许多条记录的值为null,不支持线程同步,如需要则可用Collections的synchronizeMap方法使HashMap具有同步能力
- Hashtable与HashMap类似,不同之处在于它不允许记录的键或值为null,它还支持线程同步,但也因此导致Hashtable在写入时比较慢
- LinkedHashMap保存了记录的插入顺序,用Iterator遍历时,先得到的记录是先插入的,遍历时比HashMap慢,但有特殊情况:当HashMap容量很大,但实际数据很少时遍历起来可能比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和其容量有关
- TreeMap实现了SortMap接口,能够把它保存的记录根据键值默认升序,也可以指定排序的比较器。当用Iterator遍历TreeMap时,得到的记录是排过序的
3 Object若不重写hashCode()的话,hashCode是如何计算出来的
Object的hashCode()是本地方法,其直接返回对象的内存地址作为hashCode
4 “==”比较的是什么,与equals()的区别
“= =”比较的是两个对象的内存引用,如果两个对象的引用完全相同(即指向同一个对象)时,“= =”操作返回true,否则返回false;如果“==”两边的是基本数据类型,则比较数值是否相等。
注:八大基本数据类型的封装类型中,除了Float和Double外,其他的都实现了常量池存储,即它们是对象但是“==”比较的是它们的值
关于Integer的坑
Integer a = 127;
Integer b = 128;
System.out.println(a == b); //true
Integer c = 128;
Integer d = 128;
System.out.println(c == d); //false
原因: Integer 在常量池中的存储范围为[-128,127],127在这范围内,因此是直接存储于常量池的,而128不在这范围内,所以会在堆内存中创建一个新的对象来保存这个值,所以m,n分别指向了两个不同的对象地址,故而导致了不相等。
与equals()的区别: equals方法和"= =“完全一样;但是equals方法可以重写;”=="的话,如果是值类型则比较值是否相等;如果是引用类型则判断对象地址是否相等。
关于String的坑
public class Test {
public static void main(String[] args) {
String s1 = "HelloWorld";
String s2 = new String("HelloWorld");
if (s1 == s2) {
System.out.println("s1 == s2");
} else {
System.out.println("s1 != s2");
}
if (s1.equals(s2)) {
System.out.println("s1 equals s2");
} else {
System.out.println("s1 not equals s2");
}
}
}
/*
输出:s1 != s2
s1 equals s2
*/
原因:Object 中的equals() 与 “==” 的作用相同,但String类重写了equals()方法,比较的是对象中的内容。
5 若对一个类不重写,它的equals()方法是如何比较的
比较的是对象的地址是否相等,两个对象equals为true则它们严格相等,即内存地址相等
6 说说Lamda表达式的优缺点
优点:
1.简洁
2.非常容易并行计算
3.可能代表未来的编程趋势
缺点:
1.若不用并行计算,很多时候计算速度没有比传统的for循环快
2.不容易调试
3.若其他程序员没学过lamda表达式,代码不容易让其他语言的程序员看懂
7 一个十进制的数在内存中是怎么存储的
补码的形式
8 为什么有时会出现4.0-3.6=0.40000001这种现象
原因:二进制的小数无法精确的表达十进制的小数,计算机在计算十进制小数的过程中是要先转换成二进制再进行计算的,这过程中出现了误差
9 Java支持的数据类型有哪些,什么是自动拆装箱
数据类型 | 位数 | 字节数 |
---|---|---|
btye | 8 | 1 |
short | 16 | 2 |
int | 32 | 4 |
long | 64 | 8 |
float | 32 | 4 |
double | 64 | 8 | </