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

时间:2014-02-25 05:26:53

标签: java string java.util.scanner

实际上我正在测试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");
        }

    }
}

我想知道为什么它会像这样?

谢谢...!

3 个答案:

答案 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,并且不会被垃圾回收。