如何比较爪哇的字符串?
我一直在程序中使用==
运算符来比较到目前为止的所有字符串。 但是,我遇到了一个错误,将其中一个更改为.equals()
,然后修复了错误。
==
不好吗?什么时候应该使用,不应该使用?有什么区别?
I've been using the ==
operator in my program to compare all my strings so far.
However, I ran into a bug, changed one of them into .equals()
instead, and it fixed the bug.
Is ==
bad? When should it and should it not be used? What's the difference?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(23)
==
测试引用相等性(它们是否是同一个对象)。.equals()
测试值是否相等(它们是否包含相同的数据)。Objects.equals() 在调用
.equals()
之前检查null
,因此您不必这样做(从 JDK7 开始可用,也可用在 番石榴)。因此,如果您想测试两个字符串是否具有相同的值,您可能需要使用
Objects.equals()
。来自 Java 语言规范 JLS 15.21 .3.参考相等运算符
==
和!=
:您几乎总是想要使用
Objects.equals()
。在罕见情况下,您知道您正在处理interned 字符串,您可以使用==
。从 JLS 3.10.5 开始。 字符串文字:
类似的示例也可以在 JLS 3.10.5 中找到-1。
需要考虑的其他方法
String.equalsIgnoreCase() 忽略大小写的值相等。但请注意,此方法在各种与区域设置相关的情况下可能会产生意外结果,请参阅此问题< /a>.
String.contentEquals( ) 将
String
的内容与任何CharSequence
的内容进行比较(自 Java 1.5 起可用)。使您不必在进行相等比较之前将 StringBuffer 等转换为 String,但将 null 检查留给您。==
tests for reference equality (whether they are the same object)..equals()
tests for value equality (whether they contain the same data).Objects.equals() checks for
null
before calling.equals()
so you don't have to (available as of JDK7, also available in Guava).Consequently, if you want to test whether two strings have the same value you will probably want to use
Objects.equals()
.From the Java Language Specification JLS 15.21.3. Reference Equality Operators
==
and!=
:You almost always want to use
Objects.equals()
. In the rare situation where you know you're dealing with interned strings, you can use==
.From JLS 3.10.5. String Literals:
Similar examples can also be found in JLS 3.10.5-1.
Other Methods To Consider
String.equalsIgnoreCase() value equality that ignores case. Beware, however, that this method can have unexpected results in various locale-related cases, see this question.
String.contentEquals() compares the content of the
String
with the content of anyCharSequence
(available since Java 1.5). Saves you from having to turn your StringBuffer, etc into a String before doing the equality comparison, but leaves the null checking to you.==
测试对象引用,.equals()
测试字符串值。有时看起来好像
==
比较值,因为 Java 会在幕后做一些事情来确保相同的内联字符串实际上是同一个对象。例如:
但是要小心空值!
==
可以很好地处理null
字符串,但是从以下位置调用.equals()
null 字符串会导致异常:因此,如果您知道 fooString1 可能为 null,请告诉读者,通过编写
以下内容会更短,但检查 null 的情况不太明显:
==
tests object references,.equals()
tests the string values.Sometimes it looks as if
==
compares values, because Java does some behind-the-scenes stuff to make sure identical in-line strings are actually the same object.For example:
But beware of nulls!
==
handlesnull
strings fine, but calling.equals()
from a null string will cause an exception:So if you know that
fooString1
may be null, tell the reader that by writingThe following are shorter, but it’s less obvious that it checks for null:
==
比较对象引用。.equals()
比较字符串值。有时
==
会产生比较 String 值的错觉,如下例所示:这是因为当您创建任何 String 文字时,JVM 首先在 String 池中搜索该文字,如果找到匹配项,同样的引用将被赋予新的字符串。因此,我们得到:
(a==b) ===> true
但是,
==
在以下情况下会失败:在这种情况下,对于
new String("test")
语句 new String 将在堆上创建,并且该引用将被赋予b
,因此b
将在堆上获得引用,而不是在字符串池中。现在
a
指向字符串池中的字符串,而b
指向堆上的字符串。因此我们得到:if(a==b) ===> false。
虽然
.equals()
始终比较 String 的值,因此在两种情况下都给出 true:因此使用
.equals()
总是更好。==
compares Object references..equals()
compares String values.Sometimes
==
gives illusions of comparing String values, as in following cases:This is because when you create any String literal, the JVM first searches for that literal in the String pool, and if it finds a match, that same reference will be given to the new String. Because of this, we get:
(a==b) ===> true
However,
==
fails in the following case:In this case for
new String("test")
the statement new String will be created on the heap, and that reference will be given tob
, sob
will be given a reference on the heap, not in String pool.Now
a
is pointing to a String in the String pool whileb
is pointing to a String on the heap. Because of that we get:if(a==b) ===> false.
While
.equals()
always compares a value of String so it gives true in both cases:So using
.equals()
is always better.==
操作员检查两个字符串是否完全是同一对象。.equals()
方法将检查两个字符串是否具有相同的值。The
==
operator checks to see if the two strings are exactly the same object.The
.equals()
method will check if the two strings have the same value.Java 中的字符串是不可变的。这意味着每当您尝试更改/修改字符串时,您都会得到一个新实例。您无法更改原始字符串。这样做是为了可以缓存这些字符串实例。典型的程序包含大量字符串引用,缓存这些实例可以减少内存占用并提高程序的性能。
当使用 == 运算符进行字符串比较时,您不是在比较字符串的内容,而是实际上在比较内存地址。如果它们相等,则返回 true,否则返回 false。而字符串中的 equals 则比较字符串内容。
那么问题是,如果所有的字符串都缓存在系统中,为什么
==
返回 false 而 equals 返回 true?嗯,这是可能的。如果您创建一个像String str = new String("Testing")
这样的新字符串,您最终会在缓存中创建一个新字符串,即使缓存已经包含具有相同内容的字符串。简而言之,"MyString" == new String("MyString")
将始终返回 false。Java 还讨论了函数 intern(),该函数可用于字符串,使其成为缓存的一部分,因此
"MyString" == new String("MyString").intern()
将返回 true 。注意: == 运算符比 equals 快得多,因为您正在比较两个内存地址,但您需要确保代码不会在代码中创建新的 String 实例。否则你会遇到错误。
Strings in Java are immutable. That means whenever you try to change/modify the string you get a new instance. You cannot change the original string. This has been done so that these string instances can be cached. A typical program contains a lot of string references and caching these instances can decrease the memory footprint and increase the performance of the program.
When using == operator for string comparison you are not comparing the contents of the string, but are actually comparing the memory address. If they are both equal it will return true and false otherwise. Whereas equals in string compares the string contents.
So the question is if all the strings are cached in the system, how come
==
returns false whereas equals return true? Well, this is possible. If you make a new string likeString str = new String("Testing")
you end up creating a new string in the cache even if the cache already contains a string having the same content. In short"MyString" == new String("MyString")
will always return false.Java also talks about the function intern() that can be used on a string to make it part of the cache so
"MyString" == new String("MyString").intern()
will return true.Note: == operator is much faster than equals just because you are comparing two memory addresses, but you need to be sure that the code isn't creating new String instances in the code. Otherwise you will encounter bugs.
确保您了解原因。这是因为
==
比较只比较引用;equals()
方法对内容进行逐字符比较。当您为
a
和b
调用 new 时,每个人都会获得一个指向字符串表中的"foo"
的新引用。参考文献不同,但内容是一样的。Make sure you understand why. It's because the
==
comparison only compares references; theequals()
method does a character-by-character comparison of the contents.When you call new for
a
andb
, each one gets a new reference that points to the"foo"
in the string table. The references are different, but the content is the same.是的,这很糟糕...
==
表示您的两个字符串引用完全是同一对象。您可能已经听说过这种情况,因为Java保留了一个字面的表(它确实如此),但并非总是如此。一些字符串以不同的方式加载,从其他字符串等构建,因此您绝对不能假设两个相同的字符串存储在同一位置。平等为您提供了真正的比较。
Yea, it's bad...
==
means that your two string references are exactly the same object. You may have heard that this is the case because Java keeps sort of a literal table (which it does), but that is not always the case. Some strings are loaded in different ways, constructed from other strings, etc., so you must never assume that two identical strings are stored in the same location.Equals does the real comparison for you.
是的,
==
对比较字符串不利(除非您知道它们是规范的)。==
只需比较对象引用。.equals()
测试平等。对于字符串而言,通常它们会相同,但是正如您发现的那样,这并不能始终保证。Yes,
==
is bad for comparing Strings (any objects really, unless you know they're canonical).==
just compares object references..equals()
tests for equality. For Strings, often they'll be the same but as you've discovered, that's not guaranteed always.Java 有一个字符串池,Java 在该池下管理字符串对象的内存分配。请参阅 Java 中的字符串池
当您检查 (比较)两个对象,使用
==
运算符将地址相等性与字符串池进行比较。如果两个 String 对象具有相同的地址引用,则返回 true,否则返回 false。但如果您想比较两个 String 对象的内容,则必须重写 equals 方法。equals实际上是Object类的方法,但它被重写到String类中,并给出了一个新的定义来比较对象的内容。
但请注意,它尊重字符串的情况。如果您想要不区分大小写的比较,那么您必须使用 String 类的 equalsIgnoreCase 方法。
让我们来看看:
Java have a String pool under which Java manages the memory allocation for the String objects. See String Pools in Java
When you check (compare) two objects using the
==
operator it compares the address equality into the string-pool. If the two String objects have the same address references then it returnstrue
, otherwisefalse
. But if you want to compare the contents of two String objects then you must override theequals
method.equals
is actually the method of the Object class, but it is Overridden into the String class and a new definition is given which compares the contents of object.But mind it respects the case of String. If you want case insensitive compare then you must go for the equalsIgnoreCase method of the String class.
Let's See:
我同意zacherates的回答。
但您可以做的是对非文字字符串调用
intern()
。来自 zacherates 示例:
如果您实习,非文字字符串相等性为
true
:I agree with the answer from zacherates.
But what you can do is to call
intern()
on your non-literal strings.From zacherates example:
If you intern the non-literal String equality is
true
:==
比较 Java 中的对象引用,对于String
对象也不例外。要比较对象(包括
String
)的实际内容,必须使用equals
方法。如果使用
==
比较两个String
对象结果为true
,那是因为String
对象被拘留,并且 Java 虚拟机有多个引用指向String
的同一个实例。人们不应期望使用==
将包含相同内容的一个String
对象与另一个String
对象进行比较,以评估为true.
==
compares object references in Java, and that is no exception forString
objects.For comparing the actual contents of objects (including
String
), one must use theequals
method.If a comparison of two
String
objects using==
turns out to betrue
, that is because theString
objects were interned, and the Java Virtual Machine is having multiple references point to the same instance ofString
. One should not expect that comparing oneString
object containing the same contents as anotherString
object using==
to evaluate astrue
..equals()
比较类中的数据(假设该函数已实现)。==
比较指针位置(对象在内存中的位置)。如果两个对象(不谈论基元)都指向相同的对象实例,则
==
返回 true。如果两个对象包含相同的数据,
.equals()
返回 trueequals()
与 Java 中的==
这可能对你有帮助。
.equals()
compares the data in a class (assuming the function is implemented).==
compares pointer locations (location of the object in memory).==
returns true if both objects (NOT TALKING ABOUT PRIMITIVES) point to the SAME object instance..equals()
returns true if the two objects contain the same dataequals()
Versus==
in JavaThat may help you.
==
执行引用相等性检查,检查两个对象(本例中为字符串)是否引用内存中的同一对象。equals()
方法将检查两个对象的内容或状态是否相同。显然
==
更快,但如果您只想判断 2 个String
是否包含相同的文本,则在许多情况下会(可能)给出错误结果。绝对推荐使用
equals()
方法。不用担心性能。鼓励使用 String.equals() 的一些事情:
String.equals()
的实现首先检查引用相等性(使用==
),如果两个字符串通过引用相同,则不再执行进一步的计算!String.equals()
接下来将检查字符串的长度。这也是一个快速操作,因为String
类存储字符串的长度,不需要计算字符或代码点。如果长度不同,则不执行进一步检查,我们知道它们不可能相等。总而言之,即使我们保证字符串是实习生,使用 equals() 方法仍然不是人们想象的那样的开销,这绝对是推荐的方法。如果您想要有效的引用检查,请使用枚举,其中语言规范和实现保证相同的枚举值将是相同的对象(通过引用)。
==
performs a reference equality check, whether the 2 objects (strings in this case) refer to the same object in the memory.The
equals()
method will check whether the contents or the states of 2 objects are the same.Obviously
==
is faster, but will (might) give false results in many cases if you just want to tell if 2String
s hold the same text.Definitely the use of the
equals()
method is recommended.Don't worry about the performance. Some things to encourage using
String.equals()
:String.equals()
first checks for reference equality (using==
), and if the 2 strings are the same by reference, no further calculation is performed!String.equals()
will next check the lengths of the strings. This is also a fast operation because theString
class stores the length of the string, no need to count the characters or code points. If the lengths differ, no further check is performed, we know they cannot be equal.When all is said and done, even if we have a guarantee that the strings are interns, using the
equals()
method is still not that overhead that one might think, definitely the recommended way. If you want an efficient reference check, then use enums where it is guaranteed by the language specification and implementation that the same enum value will be the same object (by reference).如果您像我一样,当我第一次开始使用 Java 时,我想使用“==”运算符来测试两个 String 实例是否相等,但无论好坏,这都不是在 Java 中执行此操作的正确方法。
在本教程中,我将演示几种正确比较 Java 字符串的不同方法,从我最常使用的方法开始。在本 Java 字符串比较教程的最后,我还将讨论为什么“==”运算符在比较 Java 字符串时不起作用。
选项1:使用equals方法比较Java字符串
大多数时候(也许是 95% 的时间)我用 Java String 类的 equals 方法比较字符串,如下所示:
这个 String equals 方法查看两个 Java 字符串,如果它们包含完全相同的字符串,他们被认为是平等的。
看一下使用 equals 方法进行的快速字符串比较示例,如果运行以下测试,则两个字符串不会被视为相等,因为字符不完全相同(字符的大小写不同):
但是,当两个字符串包含完全相同的字符串时,equals 方法将返回 true,如下例所示:
选项 2:使用 equalsIgnoreCase 方法进行字符串比较
在某些字符串比较测试中,您需要忽略字符串是否为大写或小写。当您想以这种不区分大小写的方式测试字符串是否相等时,请使用 String 类的 equalsIgnoreCase 方法,如下所示:
选项 3:使用compareTo 方法进行 Java String 比较
还有第三种方法比较 Java 字符串的不太常见的方法,那就是使用 String 类的compareTo 方法。如果两个字符串完全相同,compareTo 方法将返回值 0(零)。下面是此字符串比较方法的一个简单示例:
当我在 Java 中撰写有关相等概念的文章时,请务必注意 Java 语言在基本 Java Object 类中包含 equals 方法。每当您创建自己的对象并且想要提供一种方法来查看对象的两个实例是否“相等”时,您应该在类中重写(并实现)此 equals 方法(与 Java 语言提供的方式相同) String equals 方法中的这种相等/比较行为)。
您可能想看看这个==,。 equals()、compareTo() 和compare()
If you're like me, when I first started using Java, I wanted to use the "==" operator to test whether two String instances were equal, but for better or worse, that's not the correct way to do it in Java.
In this tutorial I'll demonstrate several different ways to correctly compare Java strings, starting with the approach I use most of the time. At the end of this Java String comparison tutorial I'll also discuss why the "==" operator doesn't work when comparing Java strings.
Option 1: Java String comparison with the equals method
Most of the time (maybe 95% of the time) I compare strings with the equals method of the Java String class, like this:
This String equals method looks at the two Java strings, and if they contain the exact same string of characters, they are considered equal.
Taking a look at a quick String comparison example with the equals method, if the following test were run, the two strings would not be considered equal because the characters are not the exactly the same (the case of the characters is different):
But, when the two strings contain the exact same string of characters, the equals method will return true, as in this example:
Option 2: String comparison with the equalsIgnoreCase method
In some string comparison tests you'll want to ignore whether the strings are uppercase or lowercase. When you want to test your strings for equality in this case-insensitive manner, use the equalsIgnoreCase method of the String class, like this:
Option 3: Java String comparison with the compareTo method
There is also a third, less common way to compare Java strings, and that's with the String class compareTo method. If the two strings are exactly the same, the compareTo method will return a value of 0 (zero). Here's a quick example of what this String comparison approach looks like:
While I'm writing about this concept of equality in Java, it's important to note that the Java language includes an equals method in the base Java Object class. Whenever you're creating your own objects and you want to provide a means to see if two instances of your object are "equal", you should override (and implement) this equals method in your class (in the same way the Java language provides this equality/comparison behavior in the String equals method).
You may want to have a look at this ==, .equals(), compareTo(), and compare()
功能:
测试:
Function:
Test:
==
运算符检查两个引用是否指向同一个对象。.equals()
检查实际的字符串内容(值)。请注意,
.equals()
方法属于类Object
(所有类的超类)。您需要根据类要求重写它,但对于 String 它已经实现,并且它检查两个字符串是否具有相同的值。案例1
原因:创建的不带 null 的字符串文字存储在堆的 permgen 区域的字符串池中。因此 s1 和 s2 都指向池中的同一个对象。
案例2
原因:如果使用
new
关键字创建 String 对象,则会在堆上为其分配单独的空间。The
==
operator check if the two references point to the same object or not..equals()
check for the actual string content (value).Note that the
.equals()
method belongs to classObject
(super class of all classes). You need to override it as per you class requirement, but for String it is already implemented, and it checks whether two strings have the same value or not.Case 1
Reason: String literals created without null are stored in the String pool in the permgen area of heap. So both s1 and s2 point to same object in the pool.
Case 2
Reason: If you create a String object using the
new
keyword a separate space is allocated to it on the heap.==
比较对象的引用值,而java.lang.String
类中的equals()
方法比较equals()
的内容code>String 对象(到另一个对象)。==
compares the reference value of objects whereas theequals()
method present in thejava.lang.String
class compares the contents of theString
object (to another object).我认为,当您定义
字符串
时,您会定义对象。因此,您需要使用.equals()
。当您使用原始数据类型时,您会使用==
,但使用String
(和任何对象),必须使用.equals()
。I think that when you define a
String
you define an object. So you need to use.equals()
. When you use primitive data types you use==
but withString
(and any object) you must use.equals()
.如果
java.lang.Object
类中存在equals()
方法,并且期望检查对象状态的等效性!这意味着对象的内容。而==
运算符应该检查实际的对象实例是否相同。示例
考虑两个不同的引用变量,
str1
和str2
:如果您使用
equals()
,您将得到如果使用
==
,则输出为TRUE
。现在您将得到
FALSE
作为输出,因为str1
和str2
都指向两个不同的对象,即使它们共享相同的字符串内容。这是因为new String()
每次都会创建一个新对象。If the
equals()
method is present in thejava.lang.Object
class, and it is expected to check for the equivalence of the state of objects! That means, the contents of the objects. Whereas the==
operator is expected to check the actual object instances are same or not.Example
Consider two different reference variables,
str1
andstr2
:If you use the
equals()
You will get the output as
TRUE
if you use==
.Now you will get the
FALSE
as output, because bothstr1
andstr2
are pointing to two different objects even though both of them share the same string content. It is because ofnew String()
a new object is created every time.操作员 == 始终用于对象参考比较,而字符串类 .equals()方法被覆盖为内容比较< /strong>:
Operator == is always meant for object reference comparison, whereas the String class .equals() method is overridden for content comparison:
所有对象都可以保证具有
.equals()
方法,因为对象包含.equals()
,返回布尔值。如果需要进一步的定义定义,则覆盖此方法是子类的工作。没有它(即使用==
),仅在两个对象之间检查内存地址以保持平等。字符串覆盖此.equals()
方法,而不是使用内存地址,而是返回字符级别的字符串比较以获得平等。一个关键要注意的是,字符串存储在一个块池中,因此一旦创建了字符串,它将永远存储在同一地址的程序中。字符串不会改变,它们是不变的。这就是为什么如果您有大量的字符串处理要做,使用常规字符串串联是一个坏主意的原因。相反,您将使用提供的
StringBuilder
类。请记住,该字符串的指针可能会更改,如果您有兴趣查看两个指针是否相同==
是一个很好的方法。字符串本身没有。All objects are guaranteed to have a
.equals()
method since Object contains a method,.equals()
, that returns a boolean. It is the subclass' job to override this method if a further defining definition is required. Without it (i.e. using==
) only memory addresses are checked between two objects for equality. String overrides this.equals()
method and instead of using the memory address it returns the comparison of strings at the character level for equality.A key note is that strings are stored in one lump pool so once a string is created it is forever stored in a program at the same address. Strings do not change, they are immutable. This is why it is a bad idea to use regular string concatenation if you have a serious of amount of string processing to do. Instead you would use the
StringBuilder
classes provided. Remember the pointers to this string can change and if you were interested to see if two pointers were the same==
would be a fine way to go. Strings themselves do not.您还可以使用
compareTo()
方法来比较两个字符串。如果compareTo结果为0,则两个字符串相等,否则比较的字符串不相等。==
比较引用而不比较实际字符串。如果您确实使用 new String(somestring).intern() 创建了每个字符串,那么您可以使用 == 运算符来比较两个字符串,否则使用 equals() 或compareTo 方法只能使用。You can also use the
compareTo()
method to compare two Strings. If the compareTo result is 0, then the two strings are equal, otherwise the strings being compared are not equal.The
==
compares the references and does not compare the actual strings. If you did create every string usingnew String(somestring).intern()
then you can use the==
operator to compare two strings, otherwise equals() or compareTo methods can only be used.在Java中,当使用
==
运算符比较2个对象时,它检查对象是否涉及内存中的同一位置。换句话说,它检查了两个对象名称是否基本上是引用了同一内存位置。Java
字符串
类实际覆盖默认equals()
在object
类中实现 - 它覆盖了该方法,以便仅检查值字符串,而不是记忆中的位置。这意味着,如果您调用
equals()
进行比较2字符串
对象的方法,那么只要字符的实际顺序相等,两个对象都被认为是相等的。In Java, when the
==
operator is used to compare 2 objects, it checks to see if the objects refer to the same place in memory. In other words, it checks to see if the 2 object names are basically references to the same memory location.The Java
String
class actually overrides the defaultequals()
implementation in theObject
class – and it overrides the method so that it checks only the values of the strings, not their locations in memory.This means that if you call the
equals()
method to compare 2String
objects, then as long as the actual sequence of characters is equal, both objects are considered equal.