Java中equals()与==的区别
来源:互联网 发布:明山控股集团知乎 编辑:程序博客网 时间:2024/05/17 02:48
java中的数据类型,可分为两类:
1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean
2.复合数据类型(类)
3。为什么equals重写后hashCode必须要重写?
- public
static void main(String[] args) { - String
s1 = "Monday"; - String
s2 = "Monday"; - if
(s1 == s2) - {
- System.out.println("s1
== s2");} - else{
- System.out.println("s1
!= s2");} -
} -
}
public class TestString { public static void main(String[] args) { String s1 = "Monday"; String s2 = "Monday"; if (s1 == s2) { System.out.println("s1 == s2");} else{ System.out.println("s1 != s2");} } }
2.再稍微改动一下程序,会有更奇怪的发现:
- public
static void main(String[] args) { - String
s1 = "Monday"; - String
s2 = new String("Monday"); - 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");} - }
- }
public class TestString { public static void main(String[] args) { String s1 = "Monday"; String s2 = new String("Monday"); 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");} } }我们将s2用new操作符创建
程序输出:
s1 != s2
s1 equals s2
说明:s1 s2分别引用了两个"Monday"String对象
3. 字符串缓冲池
原来,程序在运行的时候会创建一个字符串缓冲池当使用 s2 = "Monday" 这样的表达是创建字符串的时候,程序首先会在这个String缓冲池中寻找相同值的对象,在第一个程序中,s1先被放到了池中,所以在s2被创建的时候,程序找到了具有相同值的 s1
将s2引用s1所引用的对象"Monday"
第二段程序中,使用了 new 操作符,他明白的告诉程序:"我要一个新的!不要旧的!"于是一个新的"Monday"Sting对象被创建在内存中。他们的值相同,但是位置不同,一个在池中游泳一个在岸边休息。哎呀,真是资源浪费,明明是一样的非要分开做什么呢?
4.再次更改程序:
- public
static void main(String[] args) { - String
s1 = "Monday"; - String
s2 = new String("Monday"); - s2
= s2.intern(); - 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");} - }
- }
public class TestString { public static void main(String[] args) { String s1 = "Monday"; String s2 = new String("Monday"); s2 = s2.intern(); 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");} } }这次加入:s2 = s2.intern();
程序输出:
s1 == s2
s1 equals s2
原来,(java.lang.String的intern()方法"abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方法没什么用处。但实际上,它做了个小动作:检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把"abc"添加到字符串池中,然后再返回它的引用。
主要内容,而且要将 = =和 equals列为重要的对比概念来学习
1、声明格式
其比较规则为:当参数obj引用的对象与当前对象为同一个对象时,就返回true,否则返回false.
则animal1==animal2
而JDK类中有一些类覆盖了oject类的equals()方法,比较规则为:如果两个对象的类型一致,并且内容一致,则返回true,这些类有:
java.io.file,java.util.Date,java.lang.string,包装类(Integer,Double等)
比如
Integer
Integer int2=new Integer(1);
String str1=new String("hello");
String str2=new String("hello");
int1==int2
int1.equals(int2)
str1==str2
str1.equals(str2)
public class Person{
public boolean equals(Object o)
{
if (!o instanceof Person) return false;
final Person other=(Person)o;
else
}
}
注意,在重写equals方法时,要注意满足离散数学上的特性
1、 自反性
2
3
4
5
先看看代码呗
-
{ -
-
Integer i1=new Integer(13); -
Integer i2=new Integer(13); -
System.out.println(i1==i2);//false -
-
-
int i3 = 1150; -
int i4 = 1150; -
-
System.out.println(i3==i4);//true -
-
-
int i5=13; -
System.out.println(i2==i5);//true -
System.out.println(i5==i1);//true -
-
-
Integer i6 = 12; -
Integer i7 = 12; -
System.out.println(i6==i7);//true -
i6 = 200; -
i7 = 200; -
System.out.println(i6==i7);//false -
-
}
public static void main(String args[]) { Integer i1=new Integer(13); Integer i2=new Integer(13); System.out.println(i1==i2);//false int i3 = 1150; int i4 = 1150; System.out.println(i3==i4);//true int i5=13; System.out.println(i2==i5);//true System.out.println(i5==i1);//true Integer i6 = 12; Integer i7 = 12; System.out.println(i6==i7);//true i6 = 200; i7 = 200; System.out.println(i6==i7);//false }
第一个问题应该很好理解,i1和i2是包装类型的引用,存放在栈区,new Integer(13)生成了两份,存在于堆区。i1和i2指向了堆内存中不同的地址,所以
System.out.println(i1==i2);//false
第三个问题,哎呀,这问题曾经着实让我纠结了很久。以前是这样子想的,因为 i5 是基本类型int的变量,所以i5是存放在栈内存中的,13这个数值也是存放在栈内存中的,i5 指向 13。可以这么理解吧,而引用变量i2指向的是堆内存中13这个integer对象,既然在i2和i3指向的内存地址不同,为什么“System.out.println(i2==i5)” 的结果为 true?
当时是不是脑子不转了,一句话 拆箱之后,值比较。其他就不要想了。
第四个问题看着挺有意思的,都是Integer类型,为什么这里存在一个范围呢?挺诡异的吧。其实看看源码就知道了。这里java在对装箱过程处理的时候,对-128到127之间的数值进行了一个缓存,我猜测,应该是这些数值比较常用,而且在处理的时候效率应该更高一些。
-
- //
value of java.lang.Integer.IntegerCache.high property (obtained during VM init) - private
static String integerCacheHighPropValu e; -
- static
void getAndRemoveCachePropert ies() { -
if (!sun.misc.VM.isBooted()) { -
Properties props = System.getProperties(); -
integerCacheHighPropValu e = -
(String)props.remove("java.lang.Integer.IntegerCache.high"); -
if (integerCacheHighPropValu e != null) -
System.setProperties(props); // remove from system props -
} - }
-
- private
static class IntegerCache { -
static final int high; -
static final Integer cache[]; -
-
static { -
final int low = -128; -
-
// high value may be configured by property -
int h = 127; -
if (integerCacheHighPropValu e != null) { -
// Use Long.decode here to avoid invoking methods that -
// require Integer's autoboxing cache to be initialized -
int i = Long.decode(integerCacheHighPropValu e).intValue(); -
i = Math.max(i, 127); -
// Maximum array size is Integer.MAX_VALUE -
h = Math.min(i, Integer.MAX_VALUE - -low); -
} -
high = h; -
-
cache = new Integer[(high - low) + 1]; -
int j = low; -
for(int k = 0; k < cache.length; k++) -
cache[k] = new Integer(j++); -
} -
-
private IntegerCache() {} - }
-
-
- public
static Integer valueOf(int i) { -
if(i >= -128 && i <= IntegerCache.high) -
return IntegerCache.cache[i + 128]; -
else -
return new Integer(i); - }
- 【java中==与equals的区别】java中==与equals的区别
- java中equals的用法,与“==”的区别
- java中“==”与equals区别
- java中equals与==区别
- Java中"equals()"与"=="区别
- Java中equals()与==区别
- Java中equals与==区别
- java中“==” 与 equals 区别
- java中equals与==的区别
- java中equals() 与==的区别
- java中“==”与“equals”的区别
- java中“==”与“equals”的区别
- Java中==与equals的区别
- java中equals与==的区别
- java中equals与==的区别
- Java中== 与 equals的区别
- java中== 与equals的区别
- java中==与equals的区别
- 对决
- Cocos2d-x lua 触屏
- Redhatx86系统KVM虚拟机网络配置 —Bridge方式
- 过年什么的,真是越来越没意思了
- SDN影响思考
- Java中equals()与==的区别
- 画图
- JavaScript小结
- 如何定义职业规划
- 动态代理-----深度学习(Proxy,InvocationHandler),含$Proxy0源码
- CF contest/389
- 大学生程序员的意义
- HDU-3635 Dragon Balls 并查集路径压缩
- TP-LINK TL-WN823N 300M driver for linux