文章目录
equals和hashCode,为什么要重写?
/**
* Returns a hash code value for the object. This method is
* supported for the benefit of hash tables such as those provided by
这个方法是为了支持哈希表
* {@link java.util.HashMap}.
* <p>
* The general contract of {@code hashCode} is:
* <ul>
* <li>Whenever it is invoked on the same object more than once during
* an execution of a Java application, the {@code hashCode} method
* must consistently return the same integer, provided no information
* used in {@code equals} comparisons on the object is modified.
在一个程序中,不论对一个对象(对象没有被修改的情况下)调用多少次这个方法,返回值都应该是一样的
* This integer need not remain consistent from one execution of an
* application to another execution of the same application.
对象的哈希码没有必要在不同的程序中保持相同的值。
* <li>If two objects are equal according to the {@code equals(Object)}
* method, then calling the {@code hashCode} method on each of
* the two objects must produce the same integer result.
如果2个对象使用equals方法进行比较并且相同的话,那么这2个对象的hashCode方法的值也必须相等。
* <li>It is <em>not</em> required that if two objects are unequal
* according to the {@link java.lang.Object#equals(java.lang.Object)}
* method, then calling the {@code hashCode} method on each of the
* two objects must produce distinct integer results. However, the
* programmer should be aware that producing distinct integer results
* for unequal objects may improve the performance of hash tables.
如果根据equals方法,得到两个对象不相等,那么这2个对象的hashCode值不需要必须不相同。但是,不相等的对象的hashCode值不同的话可以提高哈希表的性能。
* </ul>
* <p>
* As much as is reasonably practical, the hashCode method defined by
* class {@code Object} does return distinct integers for distinct
* objects. (This is typically implemented by converting the internal
* address of the object into an integer, but this implementation
* technique is not required by the
* Java™ programming language.)
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)
* @see java.lang.System#identityHashCode
*/
因为默认的equals方法是Object的方法,比较的是内存地址;而默认的hashcode方法返回的是对象的内存地址转换成的一个整数,实际上指的的也是内存,两个方法可以理解为比较的都是内存地址,这在实际开发的过程中在hashmap或者hashset里如果不重写的hashcode和equals方法的话会导致我们存对象的时候,把对象存进去了,取的时候却取不到想要的对象,这时候就需要重写这两个方法了,一般可以根据业务的需求重写;
首先要知道hashCode和equals的原始方法是干嘛的。hashCode是返回一个哈希值(主要是内存地址),equals比较的是地址值。当我们没有重写这两个方法的时候,创建两个对象,成员变量完全一样。把这两个对象放入map集合,你会发现不会报错,为什么?因为map底层是哈希表,这两个对象的哈希值明显不一样,所以可以放进去。而有种情况,当把对象作为键的时候,如果还是这两个对象,那就会造成map的键重复(我们认为的重复),为了满足需求,就得去重写hashCode和equals,把我们想要的唯一性表达出来,也就是成员变量相同的对象认为是一个对象,这样map集合内的键就不会“重复”了。
equals()和==的区别
一、对象类型不同
1、equals():是超类Object中的方法。
2、==:是操作符。
二、比较的对象不同
1、equals():用来检测两个对象是否相等,即两个对象的内容是否相等。
2、==:用于比较引用和比较基本数据类型时具有不同的功能。
三、运行速度不同
1、equals():没有==运行速度快。
2、:运行速度比equals()快,因为只是比较引用。
扩展资料:
equals()和==的源码定义:
public boolean equals(Object obj) {
return (this == obj);
}
由equals的源码可以看出这里定义的equals与==是等效的(Object类中的equals没什么区别),不同的原因就在于有些类(像String、Integer等类)对equals进行了重写。
但是没有对equals进行重写的类就只能从Object类中继承equals方法,其equals方法与==就也是等效的,除非在此类中重写equals。
对equals重新需要注意五点:
1、自反性:对任意引用值X,x.equals(x)的返回值一定为true;
2、对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
3、传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true ;
4、 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变;
5、非空性:任何非空的引用值X,x.equals(null)的返回值一定为false 。
==:
== 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。
equals:
equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。
String s="abce"是一种非常特殊的形式,和new 有本质的区别。它是java中唯一不需要new 就可以产生对象的途径。
以String s=“abce”;形式赋值在java中叫直接量,它是在常量池中而不是象new一样放在压缩堆中。这种形式的字符串,在JVM内部发生字符串拘留,即当声明这样的一个字符串后,JVM会在常量池中先查找有有没有一个值为"abcd"的对象。
如果有,就会把它赋给当前引用.即原来那个引用和现在这个引用指点向了同一对象,如果没有,则在常量池中新创建一个“abcd"”,下一次如果有Strings1=“abcd”;又会将s1指向“abcd”这个对象,即以这形式声明的字符串,只要值相等,任何多个引用都指向同一对象。
而String s=new String("abcd”);和其它任何对象一样.每调用一次就产生一个对象,只要它们调用。
也可以这么理解:String str="hello”;先在内存中找是不是有“hello”这个对象,如果有,就让str指向那个“hello”。
如果内存里没有"hello",就创建一个新的对象保存"hello”.String str=new String(“hello")就是不管内存里是不是已经有"hello"这个对象,都新建一个对象保存"hello"。
Java中的事务
事务
事务的提交与回滚
数据库回滚(rollback)和撤销(undo)的区别
redo和undo日志
MySQL中是如何实现事务提交和回滚的?
为了保证数据的持久性,数据库在执行SQL操作数据之前会先记录redo log和undo log
redo log是重做日志,通常是物理日志,记录的是物理数据页的修改,它用来恢复提交后的物理数据页
undo log是回滚日志,用来回滚行记录到某个版本,undo log一般是逻辑日志,根据行的数据变化进行记录
redo/undo log都是写先写到日志缓冲区,再通过缓冲区写到磁盘日志文件中进行持久化保存
undo日志还有一个用途就是用来控制数据的多版本(MVCC)
简单理解就是:
redo log是用来恢复数据的,用于保障已提交事务的持久性
undo log是用来回滚事务的,用于保障未提交事务的原子性
String,StringBuffer与StringBuilder的区别|线程安全与线程不安全
https://blog.csdn.net/qq_36814756/article/details/84137257
关于String a=new String(“abc”)与String a="abc"的各创建了几个对象
https://blog.csdn.net/aitengteng1/article/details/87882996
函数式编程
http://www.ruanyifeng.com/blog/2012/04/functional_programming.html
Java Socket里面close()和shutdown()有啥区别?
float f=3.4会出现什么问题
Java中为何 float f = 3.4会报错
Java中出现一个小数时,如果没有明确指出类型,那么默认是double类型的,所以在编译时,3.4为double类型的赋给float类型的f变量,为向下转型,会丢失精度所以报错。
怎么解决
1.强制类型转化 float f = (float)3.4
2.明确类型:float f = 3.4f
反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射就是把java类中的各种成分映射成一个个的Java对象。
用处:最主要的用途就是开发框架,别的还有变些开发工具。
功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
意义:
首先,反射机制极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力。
其次,通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类。
再次,使用反射机制能够在运行时构造一个类的对象、判断一个类所具有的成员变量和方法、调用一个对象的方法。
最后,反射机制是构建框架技术的基础所在,使用反射可以避免将代码写死在框架中。
正是反射有以上的特征,所以它能动态编译和创建对象,极大的激发了编程语言的灵活性,强化了多态的特性,进一步提升了面向对象编程的抽象能力。
实现原理
char与byte的区别
https://blog.csdn.net/luoweifu/article/details/7770588
Java包的静态导入 import static和import的区别
https://www.jianshu.com/p/3a2d94e4f53b
包装类型的好处
1、泛型,对象可以作为泛型参数,基本类型是不可以的。
2、内部封装了一些方法。
3、前端或数据库传来的数据如果是null,只能用包装类型接收,使用基本类型就会报错。
4、包装类型有引用。
Java8新的日期时间类
https://www.jianshu.com/p/3208f0b31dd5