如何比较java中的字符串?

ffx8fchx  于 2021-08-20  发布在  Java
关注(0)|答案(14)|浏览(274)

这个问题的答案是社区的努力。编辑现有答案以改进此帖子。它目前不接受新的答案或互动。

我一直在使用 == 运算符来比较到目前为止我的所有字符串。然而,我遇到了一个bug,将其中一个修改为 .equals() 相反,它修复了这个bug。
== 糟糕?什么时候应该使用,什么时候不应该使用?有什么区别?

j9per5c4

j9per5c41#

== 测试引用相等性(它们是否为同一对象)。 .equals() 测试值是否相等(逻辑上是否“相等”)。
equals()检查 null 打电话之前 .equals() 因此,您不必这样做(从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() . 在罕见的情况下,如果您知道您正在处理的是内部字符串,您可以使用 == .
来自jls 3.10.5。字符串文字:
此外,字符串文字总是引用类的同一示例 String . 这是因为字符串文字——或者更一般地说,是常量表达式(§15.28)的值的字符串——被“插入”,以便使用该方法共享唯一示例 String.intern .
类似示例也可在jls 3.10.5-1中找到。
β-其它方法的考虑
忽略大小写的string.equalsignorecase()值相等。但是,请注意,在各种与区域设置相关的情况下,此方法可能会产生意外的结果,请参见此问题。
contentequals()比较 String 有任何 CharSequence (从Java1.5开始提供)。在进行相等比较之前,无需将stringbuffer等转换为字符串,但将空检查留给您。

c0vxltue

c0vxltue2#

== 测试对象引用, .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"));

以下内容较短,但不太明显的是它会检查null:

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

pvcm50d13#

== 比较对象引用。 .equals() 比较字符串值。
有时 == 给出比较字符串值的错觉,如以下情况:

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

这是因为,当您创建任何字符串文字时,jvm首先在字符串池中搜索该文字,如果找到匹配项,则会向新字符串提供相同的引用。因此,我们得到:
(a==b)==>true

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)==>false。

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

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

虽然 .equals() 始终比较字符串的值,以便在两种情况下均为真:

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() 总是更好。

um6iljoc

um6iljoc4#

这个 == 操作员检查两个字符串是否完全相同。
这个 .equals() 方法将检查两个字符串是否具有相同的值。

zc0qhyus

zc0qhyus5#

java中的字符串是不可变的。这意味着无论何时尝试更改/修改字符串,都会得到一个新示例。不能更改原始字符串。这样做是为了缓存这些字符串示例。一个典型的程序包含很多字符串引用,缓存这些示例可以减少内存占用并提高程序的性能。
当使用==运算符进行字符串比较时,您不是在比较字符串的内容,而是在比较内存地址。如果两者相等,则返回true,否则返回false。而字符串中的equals比较字符串内容。
所以问题是如果所有的字符串都缓存在系统中,为什么会这样呢 == 返回false而等于返回true?嗯,这是可能的。如果你做了一个新的字符串 String str = new String("Testing") 即使缓存已经包含具有相同内容的字符串,也会在缓存中创建新字符串。简言之 "MyString" == new String("MyString") 将始终返回false。
java还讨论了函数intern(),该函数可用于字符串,使其成为缓存的一部分 "MyString" == new String("MyString").intern() 将返回真值。
注意:==运算符比equals快得多,因为您正在比较两个内存地址,但需要确保代码没有在代码中创建新的字符串示例。否则您将遇到bug。

pb3skfrl

pb3skfrl6#

String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true

确保你明白为什么。这是因为 == 比较只比较参考文献;这个 equals() 方法对内容进行逐字符比较。
当你打电话给新的 ab ,每一个都会得到一个指向 "foo" 在字符串表中。参考文献不同,但内容相同。

zc0qhyus

zc0qhyus7#

是的,很糟糕。。。 == 表示两个字符串引用是完全相同的对象。您可能听说过这种情况,因为java保留了某种文字表(确实如此),但情况并非总是如此。有些字符串是以不同的方式加载的,由其他字符串等构造而成,因此决不能假设两个相同的字符串存储在同一位置。
equals为您进行真正的比较。

oiopk7p5

oiopk7p58#

== 不利于比较字符串(任何对象,除非您知道它们是规范的)。 == 只是比较对象引用。 .equals() 平等测试。对于字符串,它们通常是相同的,但正如您所发现的,这并不总是可以保证的。

hsvhsicv

hsvhsicv9#

java有一个字符串池,java在其中管理字符串对象的内存分配。请参见java中的字符串池
当您使用 == 运算符,它将地址相等性与字符串池进行比较。如果两个字符串对象具有相同的地址引用,则返回 true ,否则 false . 但如果要比较两个字符串对象的内容,则必须重写 equals 方法。 equals 实际上是对象类的方法,但它被重写为string类,并给出了一个比较对象内容的新定义。

Example:
    stringObjectOne.equals(stringObjectTwo);

但请注意,它尊重字符串的情况。如果希望进行不区分大小写的比较,则必须使用string类的equalsignorecase方法。
让我们看看:

String one   = "HELLO"; 
String two   = "HELLO"; 
String three = new String("HELLO"); 
String four  = "hello"; 

one == two;   // TRUE
one == three; // FALSE
one == four;  // FALSE

one.equals(two);            // TRUE
one.equals(three);          // TRUE
one.equals(four);           // FALSE
one.equalsIgnoreCase(four); // TRUE
lg40wkob

lg40wkob10#

我同意zacherates的回答。
但你能做的就是打电话 intern() 在非文本字符串上。
来自zacherates的例子:

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

如果实习,则非文字字符串相等为 true :

new String("test").intern() == "test" ==> true
aamkag61

aamkag6111#

== 比较java中的对象引用,对于 String 物体。
用于比较对象的实际内容(包括 String ),必须使用 equals 方法。
如果将两者进行比较 String 对象使用 == 结果是 true ,那是因为 String 对象被扣押,java虚拟机有多个引用指向同一个对象示例 String . 我们不应该期望 String 对象包含与另一个对象相同的内容 String 对象使用 == 评价为 true .

gxwragnw

gxwragnw12#

.equals() 比较类中的数据(假设函数已实现)。 == 比较指针位置(对象在内存中的位置)。 == 如果两个对象(不涉及基本体)都指向同一个对象示例,则返回true。 .equals() 如果两个对象包含相同的数据,则返回true equals()== 在 java
那可能对你有帮助。

wh6knrhe

wh6knrhe13#

== 执行引用相等性检查,检查两个对象(本例中为字符串)是否引用内存中的同一对象。
这个 equals() 方法将检查两个对象的内容或状态是否相同。
明显地 == 速度更快,但在很多情况下,如果你只想知道2 String 让我们保持相同的文本。
当然是使用 equals() 推荐使用该方法。
不要担心性能。一些鼓励使用的东西 String.equals() :
实施 String.equals() 首先检查引用相等性(使用 == ),如果两个字符串通过引用相同,则不执行进一步的计算!
如果两个字符串引用不相同, String.equals() 接下来将检查字符串的长度。这也是一个快速操作,因为 String 类存储字符串的长度,无需计算字符或代码点。如果长度不同,则不进行进一步检查,我们知道它们不能相等。
只有到了这一步,才会对两个字符串的内容进行实际比较,这将是一个简单的比较:不会对所有字符进行比较,如果我们发现一个不匹配的字符(在两个字符串中的相同位置),则不会再检查其他字符。
当一切都说了又做了,即使我们保证字符串是实习生,使用 equals() 方法的开销仍然没有人们想象的那么大,这绝对是推荐的方法。如果希望进行有效的引用检查,那么在语言规范和实现保证相同的枚举值将是相同的对象(通过引用)的地方使用枚举。

polkgigr

polkgigr14#

如果你像我一样,当我第一次开始使用java时,我想使用“==”操作符来测试两个字符串示例是否相等,但不管是好是坏,这就是n

相关问题