提问者:小点点

如何在Java中比较字符串?


到目前为止,我一直在我的程序中使用==运算符来比较我的所有字符串。 但是,我遇到了一个bug,将其中一个改为.equals(),它修复了这个bug。

==不好吗? 什么时候该用,什么时候不该用? 有什么不同吗?


共3个答案

匿名用户

==测试引用相等性(它们是否是同一个对象)。

.equals()测试值是否相等(它们在逻辑上是否“相等”)。

Objects.equals()在调用.equals()之前检查null,因此您不必这样做(从JDK7开始可用,在Guava中也可用)。

因此,如果您想测试两个字符串是否具有相同的值,您可能需要使用objects.equals()

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

您几乎总是希望使用objects.equals()。 在很少的情况下,您可以使用==,因为您知道您正在处理的是interned字符串。

来自JLS3.10.5。 字符串文字:

而且,字符串文本总是引用类string的同一个实例。 这是因为使用string.intern方法,字符串文本--或者更一般地,作为常量表达式值的字符串(§15.28)--被“interned”以便共享唯一的实例。

类似的例子也可以在JLS3.10.5-1中找到。

String.equalSignoRecase()忽略大小写的值相等。

contentequals()将string的内容与任何charsequence的内容(从Java 1.5开始可用)进行比较。 使您不必在进行相等性比较之前将StringBuffer等转换为字符串,但将空检查留给您。

匿名用户

==测试对象引用,.equals()测试字符串值。

有时候,==看起来好像比较值,因为Java做了一些幕后工作来确保相同的内联字符串实际上是同一个对象。

例如:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

但要小心null!

==可以处理字符串,但从空字符串调用.equals()将导致异常:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

因此,如果您知道fooString1可能为空,请通过以下方式告诉读者

System.out.print(fooString1 != null && fooString1.equals("bar"));

下面的代码比较短,但是它检查空值并不那么明显:

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required

匿名用户

==比较对象引用。

.equals()比较字符串值。

有时==会产生比较字符串值的错觉,如下所示:

String a="Test";
String b="Test";
if(a==b) ===> true

这是因为当您创建任何字符串文本时,JVM首先在字符串池中搜索该文本,如果它找到匹配项,将给出对新字符串的相同引用。 正因为如此,我们得到:

(a==b)===>>; 真

                       String Pool
     b -----------------> "test" <-----------------a

但是,==在以下情况下失败:

String a="test";
String b=new String("test");
if (a==b) ===> false

在本例中,对于new String(“test”),将在堆上创建语句new String,并且将给出对B的引用,因此将在堆上而不是在字符串池中给出对B的引用。

现在a指向字符串池中的字符串,而b指向堆上的字符串。 因此我们得到:

如果(a==b)===>; 假的。

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

.equals()总是比较字符串的值,因此在两种情况下都为true:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

因此使用.equals()总是更好。