与java.util.Scanner一起使用时字符串的奇怪行为

与java.util.Scanner一起使用时字符串的奇怪行为,java,string,java.util.scanner,Java,String,Java.util.scanner,实际上我正在测试扫描仪的功能。 我有一个非常简单的程序,它有一个包含“abc”的字符串变量。然后我使用next()方法从扫描器中读取其他字符串(值“abc”)。 然后,我使用==,检查它们是否相等,根据==(我知道我可以使用equals方法进行比较,该方法作为例外),奇怪的是,当我使用==进行比较时,它返回false,即使它们的hashcode()是相等的,equals()方法返回true import java.util.Scanner; public class Tester1234 {

实际上我正在测试扫描仪的功能。

我有一个非常简单的程序,它有一个包含“abc”的字符串变量。然后我使用next()方法从扫描器中读取其他字符串(值“abc”)。
然后,我使用==,检查它们是否相等,根据==(我知道我可以使用equals方法进行比较,该方法作为例外),奇怪的是,当我使用==进行比较时,它返回false,即使它们的hashcode()是相等的,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");
        }

    }
}
我想知道它为什么会这样


谢谢

如果我们创建这样的字符串

String str1 = "abc";
对象
str1
在字符串池中创建,如果我们创建

String str2 = new String("abc");
然后,它在堆中创建,意味着另一个新对象

这就是您的条件
if(str1==str2)
返回
false
的原因,因为它们都是不同的对象


但是hashcode是相等的,因为两者都是
“abc”
,所以
equals
方法返回
true
hashcode和equals返回true是正确的,因此它将为
str2.equals(str1)
返回true。
但是str2是一个新字符串,因此它有不同的内存地址,这就是为什么它不适用于
str2==str1
。这里比较的是内存地址,而不是字符串的内容。

关于

我知道具有相同内容的字符串将指向StringPool中的相同对象


对于代码中硬编码字符串的文本来说,这是正确的。编译器在编译时创建字符串池并使用现有引用。但是,如果您在运行时使用StringBuilder/StringBuffer构建字符串(我相信,
扫描器内部就是这样做的),那么您没有在字符串池中使用实体,这就是为什么对于相同的字符串内容,您会得到两个不同的对象(引用)。这种行为的解决方法是使用
intern()
,但它会影响性能,因为插入的字符串将进入permgen,并且不会被垃圾收集。

@mc10我知道。。。我想知道为什么这不适用于==。。。我知道具有相同内容的字符串将指向StringPool中的相同对象…因此,如果我这样做==它为什么返回flase?对不起,当您创建新字符串时,它会将原始值复制到内部
最终字符值[]
,并且hashcode是基于
值[]生成的
这就是为什么会得到相同的equals和hashcode,但当它包装在heap.dude中的新对象下时失败,即使我使用String str2=scanner.next();同样的事情..返回false