01-知识点
一.hashCode、equals、== 的区别
1.java官方推荐重写equals方法时也要重写hashCode方法。
如果2个对象的equals比较时为true,则hashCode也要相同,
如果2个对象的hashCode相同时,equals方法可以不同,
因为hashCode底层是hash算法,hash算法的原则就是,如果2个输入相同,则输出一定相同;
反之如果输出相同,输入则未必相同,比如md5算法。如果输入不同,输出相同就叫做hash冲突。
2.Object类中的hashCode、equals、toString 方法
hashCode:为native方法,具体实现和JVM厂商有关
equals: 用==比较的是内存地址值
toString: 打印的是类名和hashCode的16进制值
3.个人理解:
(1):如果一个对象继承自Object类并且没有重写hashCode、equals、toString方法,
hashCode的返回值就是该对象的内存地址值,注意Object中的hashCode方法为native方法。具体实现和JVM厂商有关。
(2):hashCode是对象的hashCode方法,equals方法是对象的equals方法,== 比较的是对象的内存地址值。
4.hashMap的存取原理:
(1):hashMap要求key值不能相同,一般意义上比较相同应该是要比较equals方法,但是如果hashMap在
put元素的时候每个已经放入的key都和新key比较equals方法的话,当hashMap中键值对比较多情况下,
效率非常低。既然是hashMap,底层实现其实是散列表,用的算法就是hash。当往hashMap中put值时:
首先计算key的hashCode方法的返回值,在散列表中查找有没有,没有,则为新元素,因为hashCode不同,
则equals一定不同,直接添加新元素;如果相同,再比较2个对应key的元素的equals方法,
如果相同,则为相同元素,替换value值,如果equals不同,则key不同,当新元素添加。
由上可知,hashMap中的所有key的equals方法一定不同,hashCode方法可能相同
5.java中equals方法的几个特性
自反性:对任意引用值X,x.equals(x)的返回值一定为true.
对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true
一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变
非空性:任何非空的引用值X,x.equals(null)的返回值一定为false
二.java 中基本类型的比较为值比较
java 中的基本类型为byte、short、char、int、long、float、double、boolean
三.java 中字符串的比较
1.java中的字符串为引用类型
2.字面量定义的字符串都会进入常量池,只会实例化一份
比如:String s1="abc"; String s2="abc"; s1==s2 为true
3.new关键字实例化字符串,每次都会重新创建
比如:String s1=new String("abc"); String s2=new String("abc"); s1==s2 为false
四.java中int、Integer的比较
1.int 之间是值比较
2.int、Integer之间比较,先将Integer 拆箱,然后再进行值比较
3.Integer 之间是引用类型比较的是地址值
注意: (1)Integer会将-128到127之间的值进行缓存,直接从缓存中拿;
范围之外的则不会被缓存,会调用new Integer 进行实例化
(2)Integer a = 127,在编译的时候,被翻译成-> Integer b1 = Integer.valueOf(127);
//Integer会将-128到127之间的值进行缓存,直接从缓存中拿;
//范围之外的则不会被缓存,会调用new Integer 进行实例化
Integer integer4 = 127;
Integer integer5 = 127;
System.out.println("integer4==integer5----->"+(integer4==integer5));//true
//-128到127之外,相当于new Integer(128)
Integer integer6 = 128;
Integer integer7 = 128;
System.out.println("integer6==integer7----->"+(integer6==integer7));//false
五.java 字符串拼接效率StringBuilder>StringBuffer>String
1.StringBuilder 是线程不安全的,效率高;StringBuffer是线程安全的,效率低
2.StringBuilder、StringBuffer都是可变的字符序列,类似于String的字符串缓存区;
而String 是不可变对象,在每一次改变字符串时都会创建新的String对象。
3.所以一般拼接字符串时+号的效率没有StringBuffer高,但是比较方便
六.HashMap、HashTable、ConcurrentHashMap的区别与联系
1.线程安全角度
HashMap线程不安全,在单线程中使用,并发环境不应该使用
HashTable线程安全,单线程和并发环境都可以使用,其内部方法都用synchronized 加锁,重量级锁,效率低
ConcurrentHashMap线程安全,单线程和并发环境都可使用,其内部用分段锁实现,效率高
2.null 值 null 键
HashMap 允许null值null键
HashTable 不允许null值null键
ConcurrentHashMap 不允许null值null键
为什么?
可以这样解释:
因为hashtable,concurrenthashmap它们是用于多线程的,并发的 ,如果map.get(key)得到了null,
不能判断到底是映射的value是null,还是因为没有找到对应的key而为空,
而用于单线程状态的hashmap却可以用containKey(key) 去判断到底是否包含了这个null。
3.HashMap的负载因子是0.75
4.初始化HashMap的时候,如果明确知道容器容量时建议制定容量大小;
因为我们没有设置初始容量大小,随着元素的不断增加,HashMap会发生多次扩容,
而HashMap中的扩容机制决定了每次扩容都需要重建hash表,是非常影响性能的
七.return 和 finally的执行先后问题
finally会在return执行之后,方法返回之前执行
理解:
1.当执行return 的时候,编译器先根据方法的返回值类型,将其存入预留的内存里;
然后再执行finally里的方法.finally执行完再从内存里取出返回值返回。方法调用完毕。
2.finally里如果return语句的话,在执行finally过程中,
修改了返回值的值,如果返回值类型为基本类型,则最终返回值不会受影响。
如果返回值类型为引用类型,则会影响最终的返回值。
如果finally里也有return语句,最终返回值结果以finally里为准
代码示例
private static int test(){
try {
System.out.println("e----->before");
int a = 8/0;
System.out.println("e----->after");
return 1;
}catch (Exception e) {
System.out.println("catch");
return 2;
}finally{//这里finally里直接return 0 那么最终的返回值就是0,而不是catch中的2
System.out.println("finally模块被执行");
return 0;
}
}
/**
* 该方法的返回值为0
* finally 中改变了基本类型的返回值变量,不会影响最终的返回值
*/
private static int test1(){
int num = -1;
try {
System.out.println("e----->before");
int a = 8/0;
System.out.println("e----->after");
return num;
}catch (Exception e) {
System.out.println("catch");
num = 0;
return num;
}finally{//finally 中改变了基本类型的返回值变量,不会影响最终的返回值,返回值为0
System.out.println("finally模块被执行");
num = 1;
}
}
/**
* finally 中改变了引用类型的返回值变量,会影响最终的返回值
* @return
*/
private static String test2(){
String s = "hello";
try {
System.out.println("e----->before");
int a = 8 / 0;
System.out.println("e----->after");
return s;
} catch (Exception e) {
System.out.println("catch----->message="+e.getMessage());
}finally{//finally 中改变了引用类型的返回值变量,会影响最终的返回值
System.out.println("finally模块执行");
s += "world";
}
return s;
}
Last updated
Was this helpful?