实际上我正在测试Scanner的功能。
我有一个非常简单的程序,它有一个包含“abc”的String变量。然后使用next()方法从Scanner读取其他字符串(值“abc”)(即使我尝试使用nextLine())。
然后我使用==进行比较,根据==检查它们是否相等(我知道我可以比较等于正常工作的等于方法),奇怪的是当我使用==进行比较时它返回false,即使他们的hashcode()s相等而且equals()方法返回true ..
import java.util.Scanner;
public class Tester1234 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String str1="abc";
System.out.println("Eneter abc");
String str2=scanner.next();
System.out.println("str1.hascode()"+str1.hashCode()+"\tstr2.hascode()"+str2.hashCode()+"\tstr2.equals(str1)"+str1.equals(str2));
if(str1==str2)
{
System.out.println("equal");
}
else
{
System.out.println("not equal");
}
}
}
我想知道为什么它会像这样?
谢谢...!
答案 0 :(得分:1)
如果我们像这样创建一个String ......
String str1 = "abc";
在String-Pool中创建的对象str1
,如果我们创建
String str2 = new String("abc");
然后,它在堆中创建,意味着另一个新的对象。
这是您的条件if(str1==str2)
返回false
的原因,因为这两者都是不同的对象。
但哈希码是相同的,因为它们都是"abc"
,所以equals
方法返回true
。
答案 1 :(得分:1)
你是正确的hashcode和equals返回true,因此它将为str2.equals(str1)
返回true。
但是str2是新的String,因此它具有不同的内存地址,这就是为什么它不适用于str2==str1
。这里你要比较内存地址而不是字符串的内容。
答案 2 :(得分:1)
你的陈述是错的
我知道具有相同内容的字符串将指向StringPool中的相同对象...
对于文字而言,whitch是代码中的硬编码字符串。编译器在编译时创建字符串池并使用现有引用。但是如果你在运行时使用StringBuilder / StringBuffer构建字符串(我认为Scanner
在内部做了什么)你不是在字符串池中使用实体,这就是为什么你会得到两个不同的对象(引用)来获得相同的字符串内容。这种行为的解决方法是使用intern()
,但它会受到性能影响,因为实体字符串会进入permgen,并且不会被垃圾回收。