package hnust.edu.grammar;
//Java中的equals方法和==运算区别
public class EqualsQeustions {
public static void main(String[] args) {
//比较字符串的问题equals和==
String str1 = "string";
String str2 = "string";
System.out.println("equals方法:::"+str1.equals(str2));
System.out.println("==运算:::"+(str1==str2));
/*
* 值类型是存储在内存中的堆栈(以后简称栈),
* 而引用类型的变量在栈中仅仅是存储引用类型变量的地址,
* 而其本身则存储在堆中。
*
* ==操作比较的是两个变量的值是否相等,
* 对于引用型变量表示的是两个变量在堆中存储的地址是否相同,
* 即栈中的内容是否相同。
*
* equals操作表示的两个变量是否是对同一个对象的引用,
* 即堆中的内容是否相同。
* result:equals方法:::true
* ==运算:::true 说明str1 与 str2 引用同一个 String 对象*/
/*
* 字符串缓冲池
* 原来,程序在运行的时候会创建一个字符串缓冲池
*
* 当使用 str1 = "string" 这样的表达是创建字符串的时候,
* 程序首先会在这个String缓冲池中寻找相同值的对象,在上面程序中,str1先被
* 放到了池中,所以在str2被创建的时候,程序找到了具有相同值的str1
* 将 str2 引用 str1 所引用的对象"string"
*
* 而在下面程序中,使用了 new 操作符,他明白的告诉程序:
* "我要一个新的!不要旧的!"于是一个新的"string"Sting对象被创建在内存中。
* 他们的值相同,但是位置不同。*/
String str3 = new String("string");
if(str2==str3) {
System.out.println("str2==str3");
}else {
System.out.println("str2!=str3");
}
if(str2.equals(str3)) {
System.out.println("str2 equals str3");
}else {
System.out.println("str2 not equals str3");
}
/*
* result:str2!=str3
* str2 equals str3
* 说明:str2 str3分别引用了两个"string"String对象*/
str3 = str3.intern();
if(str2==str3) {
System.out.println("str2==str3");
}else {
System.out.println("str2!=str3");
}
if(str2.equals(str3)) {
System.out.println("str2 equals str3");
}else {
System.out.println("str2 not equals str3");
}
/*
*result:str2==str3
*str2 equals str3
*原因就在使用了原来,java.lang.String的intern()方法
*eg:"abc".intern()方法的返回值还是字符串"abc",
*表面上看起来好像这个方法没什么用处。但实际上,
*它做了个小动作:检查字符串池里是否存在"abc"这么一个字符串,
*如果存在,就返回池里的字符串;如果不存在,该方法会把"abc"添加到字符串池中,
*然后再返回它的引用。
*注意:::把所有的String都intern()到缓冲池去,最好在用到new的时候就进行这个操作
*String s2 = new String("").intern();然后就可以用==比较两个字符串的值了*/
//比较简单数据类型和封装类中的equals和==
/*
*Java为每一个简单数据类型提供了一个封装类,有八种基本数据类型,每个基本数据类型可以封装成对象类型。
*格式为(基本数据类型)(封装成对象类型),
*int(Integer),
*char(Character),
*其余类型首字母大写即成封装类类型名。
*double (Double),
*float(Float),
*long(Long),
*short(Short),
*byte(Byte),
*boolean(Boolean).
*
*下面主要以Internet与int为例说明:
*1.int是基本的数据类型,默认值可以为0;
*2.Integer是int的封装类,默认值为null;
*3.int和Integer都可以表示某一个数值;
*4.int和Integer不能够互用,因为他们是两种不同的数据类型;*/
int iNum1 = 16;
int iNum2 = 16;
Integer iNum3 = new Integer(16);
Integer iNum4 = new Integer(16);
Integer iNum5 = 16;
Integer iNum6 = 16;
//==在jdk1.5以上的版本中,基本类型和封装类能自动转化,与String类型的对象和字符串常量类似。
System.out.println((iNum1==iNum2));//true
System.out.println((iNum1==iNum3));//true
System.out.println((iNum1==iNum5));//true
System.out.println((iNum3==iNum4));//false
System.out.println((iNum3==iNum5));//false
System.out.println((iNum3==iNum6));//false
System.out.println((iNum5==iNum6));//true
//equals 略:x.equals(null)一定返回false。
/*
* 相同数据类型,两个对象,地址不同,内容相同,
* quals比较的是2个对象的内容,所以成立。(a.equals(b),因为equals比较的是两个对象,
* 所以a,b都不能为基本数据类型,否则会出编译错误。)
* (在jdk1.5以上版本中,b可以为基本数据类型,a不可以)
* ==比较的是2个对象的地址,而equals比较的是2个对象的内容。
*
* java里equals和hashCode之间什么关系
* 只是为了维护 hashCode 方法的常规协定,才要求用equals比较的两个对象的hashCode相同。
* equals()和hashCode()都来自java.lang.Object。
* 在一般的应用中你不需要了解hashcode的用法,但当你用到hashmap,hashset等集合类时要
* 注意下hashcode。你想通过一个object的key来拿hashmap的value,hashmap的工作方法是通过你
* 传入的object的hashcode在内存中找地址,当找到这个地址后再通过equals方法来比较这个地址中
* 的内容是否和你原来放进去的一样,一样就取出value。
* 一般重写equals的时候都会重写hashCode(),当然,这个相当于一个约定,一个协议*/
}
}