提问人: 提问时间:2/5/2009 最后编辑:Nathan H 更新时间:11/12/2022 访问量:4566815
如何在 Java 中比较字符串?
How do I compare strings in Java?
问:
到目前为止,我一直在使用程序中的运算符来比较我的所有字符串。
但是,我遇到了一个错误,将其中一个改为,它修复了错误。==
.equals()
不好吗?什么时候应该使用,什么时候不应该使用?有什么区别?==
答:
==
测试引用相等性(它们是否为同一对象)。
.equals()
测试值相等性(它们是否包含相同的数据)。
Objects.equals() 在调用之前会检查,因此您不必这样做(从 JDK7 开始可用,在 Guava 中也可用)。null
.equals()
因此,如果要测试两个字符串是否具有相同的值,则可能需要使用。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
摘自 Java 语言规范 JLS 15.21.3。引用相等运算符 ==
和 !=
:
虽然可以用来比较类型的引用,但这种相等性测试可以确定两个操作数是否引用同一个对象。结果是,如果操作数是不同的对象,即使它们包含相同的字符序列 (§3.10.5, §3.10.6) 。两个字符串的内容,可以通过方法调用来测试是否相等。
==
String
String
false
String
s
t
s.equals(t)
您几乎总是想使用 .在极少数情况下,您知道自己正在处理被隔离的字符串,您可以使用 .Objects.equals()
==
此外,字符串文字总是引用类的同一实例。这是因为字符串文字(或者更一般地说,作为常量表达式 (§15.28) 值的字符串)被“嵌入”,以便使用 方法共享唯一实例。
String
String.intern
类似的示例也可以在 JLS 3.10.5-1 中找到。
其他要考虑的方法
String.equalsIgnoreCase() 值相等,忽略大小写。但是请注意,此方法在各种与区域设置相关的情况下可能会产生意外结果,请参阅此问题。
String.contentEquals() 将 的内容与 any 的内容(从 Java 1.5 开始可用)进行比较。使您不必在执行相等性比较之前将 StringBuffer 等转换为 String,但将 null 检查留给您。String
CharSequence
评论
==
==
int
int
int
==
int
equals
Objects
.equals
.equal
isEqual
isEqualTo
equals
是的,不利于比较字符串(实际上任何对象,除非您知道它们是规范的)。 只是比较对象引用。 测试是否相等。对于字符串,它们通常是相同的,但正如你所发现的,这并不总是保证的。==
==
.equals()
==
比较 Java 中的对象引用,对象也不例外。String
要比较对象(包括 String
)的实际内容,必须使用 equals
方法。
如果两个对象的比较结果是 ,那是因为这些对象被隔离了,并且 Java 虚拟机的多个引用指向 的同一实例。不应期望将一个包含相同内容的对象与另一个对象进行比较,以计算为 .String
==
true
String
String
String
String
==
true
是的,这很糟糕......
==
表示两个字符串引用是完全相同的对象。你可能听说过这种情况,因为 Java 保留了一个字面表(它确实如此),但情况并非总是如此。有些字符串以不同的方式加载,由其他字符串等构造而成,因此绝不能假设两个相同的字符串存储在同一个位置。
Equals 为您进行真正的比较。
.equals()
比较类中的数据(假设函数已实现)。 比较指针位置(对象在内存中的位置)。==
==
如果两个对象(NOT TALKING ABOUT PRIMITIVES)都指向同一个对象实例,则返回 true。 如果两个对象包含相同的数据,则返回 true equals()
Versus ==
在 Java 中.equals()
这可能会对你有所帮助。
运算符检查两个字符串是否完全相同的对象。==
该方法将检查两个字符串是否具有相同的值。.equals()
评论
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()
当您调用 new for 和 时,每个 都会获得指向字符串表中 的新引用。参考资料不同,但内容相同。a
b
"foo"
==
测试对象引用,测试字符串值。.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 字符串调用会导致异常: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
评论
==
?.
nullString1?.equals(nullString2);
validString?.equals(nullString);
我同意 zacherates 的答案。
但是你可以做的是调用你的非文字字符串。intern()
从 zacherates 示例:
// ... but they are not the same object
new String("test") == "test" ==> false
如果你实习,非文字字符串等式是:true
new String("test").intern() == "test" ==> true
评论
==
Java 中的字符串是不可变的。这意味着每当您尝试更改/修改字符串时,您都会获得一个新实例。不能更改原始字符串。这样做是为了可以缓存这些字符串实例。典型的程序包含大量字符串引用,缓存这些实例可以减少内存占用并提高程序的性能。
当使用 == 运算符进行字符串比较时,您不是在比较字符串的内容,而是在比较内存地址。如果它们都相等,否则将返回 true 和 false。而字符串中的 equals 比较字符串内容。
那么问题来了,如果所有的字符串都缓存在系统中,为什么返回 false 而等于返回 true?嗯,这是可能的。如果像这样创建一个新字符串,则最终会在缓存中创建一个新字符串,即使缓存已经包含具有相同内容的字符串。简而言之,将始终返回 false。==
String str = new String("Testing")
"MyString" == new String("MyString")
Java 还讨论了函数 intern(),该函数可用于字符串以使其成为缓存的一部分,因此将返回 true。"MyString" == new String("MyString").intern()
注意:== 运算符比 equals 快得多,因为您正在比较两个内存地址,但您需要确保代码不会在代码中创建新的 String 实例。否则,您将遇到错误。
==
比较对象的引用值,而类中存在的方法比较对象的内容(与另一个对象)。equals()
java.lang.String
String
评论
的 equals()
方法实际上在类中,而不是在 .默认的 equals()
in 不会比较内容是否相同,实际上只是在引用相同时返回 true。String
String
Object
Object
所有对象都保证有一个方法,因为 Object 包含一个返回布尔值的方法 。如果需要进一步定义,则子类的工作是重写此方法。如果没有它(即使用 ),则仅检查两个对象之间的内存地址是否相等。String 重写此方法,而不是使用内存地址,而是返回字符级别的字符串比较是否相等。.equals()
.equals()
==
.equals()
一个关键的说明是,字符串存储在一个块池中,因此一旦创建了一个字符串,它就会永远存储在同一地址的程序中。字符串不会改变,它们是不可变的。这就是为什么如果您要进行大量的字符串处理,那么使用常规字符串连接是一个坏主意。相反,您将使用提供的类。请记住,指向此字符串的指针可能会更改,如果您有兴趣查看两个指针是否相同将是一个很好的方法。字符串本身则不然。StringBuilder
==
评论
final String
String
==
比较对象引用。
.equals()
比较 String 值。
有时会给人比较 String 值的错觉,如以下情况所示:==
String a="Test";
String b="Test";
if(a==b) ===> true
这是因为当您创建任何 String 文本时,JVM 首先在 String 池中搜索该文本,如果找到匹配项,则将向新 String 提供相同的引用。正因为如此,我们得到:
(a==b) ===> 真
String Pool
b -----------------> "test" <-----------------a
但是,在以下情况下会失败:==
String a="test";
String b=new String("test");
if (a==b) ===> false
在本例中,对于语句,将在堆上创建新的 String,并且该引用将提供给 ,因此将在堆上提供引用,而不是在 String 池中。new String("test")
b
b
现在指向 String 池中的 String,同时指向堆上的 String。正因为如此,我们得到:a
b
if(a==b) ===> false。
String Pool
"test" <-------------------- a
Heap
"test" <-------------------- b
虽然总是比较 String 的值,所以在这两种情况下都给出 true:.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()
评论
.equals()
.equals()
String
String
我认为当你定义一个时,你就定义了一个对象。所以你需要使用 .当您使用原始数据类型时,您必须使用 但 with(和任何对象)必须使用 .String
.equals()
==
String
.equals()
评论
功能:
public float simpleSimilarity(String u, String v) {
String[] a = u.split(" ");
String[] b = v.split(" ");
long correct = 0;
int minLen = Math.min(a.length, b.length);
for (int i = 0; i < minLen; i++) {
String aa = a[i];
String bb = b[i];
int minWordLength = Math.min(aa.length(), bb.length());
for (int j = 0; j < minWordLength; j++) {
if (aa.charAt(j) == bb.charAt(j)) {
correct++;
}
}
}
return (float) (((double) correct) / Math.max(u.length(), v.length()));
}
测试:
String a = "This is the first string.";
String b = "this is not 1st string!";
// for exact string comparison, use .equals
boolean exact = a.equals(b);
// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote
float similarity = simple_similarity(a,b);
评论
==
equals
==
执行引用相等性检查,即 2 个对象(在本例中为字符串)是否引用内存中的同一对象。
该方法将检查 2 个对象的内容或状态是否相同。equals()
显然更快,但如果您只想判断 2 秒是否包含相同的文本,那么在许多情况下(可能会)给出错误的结果。==
String
绝对建议使用该方法。equals()
不要担心性能。鼓励使用以下几点:String.equals()
- 实现第一次检查引用相等性(使用 ),如果 2 个字符串在引用上相同,则不执行进一步的计算!
String.equals()
==
- 如果 2 个字符串引用不同,接下来将检查字符串的长度。这也是一个快速的操作,因为类存储字符串的长度,不需要计算字符或码位。如果长度不同,则不进行进一步检查,我们知道它们不能相等。
String.equals()
String
- 只有当我们走到这一步时,才会真正比较 2 个字符串的内容,这将是一个速记比较:并非所有字符都会被比较,如果我们发现一个不匹配的字符(在 2 个字符串中的相同位置),则不会检查其他字符。
总而言之,即使我们可以保证字符串是实习生,使用该方法仍然不是人们可能认为的那么开销,绝对是推荐的方法。如果需要有效的引用检查,请使用由语言规范和实现保证相同的枚举值将是同一对象(通过引用)的枚举。equals()
评论
Obviously == is faster
-- 实际上,首先检查的实施是先于其他任何事情,所以我想说速度大致相同。.equals(String)
==
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Java 有一个 String 池,Java 在该池下管理 String 对象的内存分配。请参阅 Java 中的字符串池
当您使用运算符检查(比较)两个对象时,它会将地址相等性与字符串池进行比较。如果两个 String 对象具有相同的地址引用,则返回 ,否则返回 。但是,如果要比较两个 String 对象的内容,则必须重写该方法。==
true
false
equals
equals
实际上是 Object 类的方法,但它被重写到 String 类中,并给出了一个新定义来比较 object 的内容。
Example:
stringObjectOne.equals(stringObjectTwo);
但请注意,它尊重 String 的情况。如果要进行不区分大小写的比较,则必须使用 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
评论
equalsIgnoreCase
运算符 == 始终用于对象引用比较,而 String 类 .equals() 方法被覆盖用于内容比较:
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)
还可以使用该方法比较两个 String。如果 compareTo 结果为 0,则两个字符串相等,否则被比较的字符串不相等。compareTo()
比较引用,不比较实际字符串。如果您确实使用 创建了每个字符串,则可以使用运算符来比较两个字符串,否则只能使用 equals() 或 compareTo 方法。==
new String(somestring).intern()
==
如果你像我一样,当我第一次开始使用 Java 时,我想使用“==”运算符来测试两个 String 实例是否相等,但无论好坏,这不是在 Java 中执行此操作的正确方法。
在本教程中,我将演示几种正确比较 Java 字符串的不同方法,从我最常使用的方法开始。在本 Java 字符串比较教程的最后,我还将讨论为什么在比较 Java 字符串时“==”运算符不起作用。
选项 1:Java String 与 equals 方法的比较大多数时候(可能是 95% 的时间),我将字符串与 Java String 类的 equals 方法进行比较,如下所示:
if (string1.equals(string2))
此 String equals 方法查看两个 Java 字符串,如果它们包含完全相同的字符串,则认为它们相等。
看一下使用 equals 方法的快速字符串比较示例,如果运行以下测试,则两个字符串将不被视为相等,因为字符不完全相同(字符的大小写不同):
String string1 = "foo";
String string2 = "FOO";
if (string1.equals(string2))
{
// this line will not print because the
// java string equals method returns false:
System.out.println("The two strings are the same.")
}
但是,当两个字符串包含完全相同的字符串时,equals 方法将返回 true,如下例所示:
String string1 = "foo";
String string2 = "foo";
// test for equality with the java string equals method
if (string1.equals(string2))
{
// this line WILL print
System.out.println("The two strings are the same.")
}
选项 2:使用 equalsIgnoreCase 方法进行字符串比较
在某些字符串比较测试中,您需要忽略字符串是大写还是小写。如果要以这种不区分大小写的方式测试字符串是否相等,请使用 String 类的 equalsIgnoreCase 方法,如下所示:
String string1 = "foo";
String string2 = "FOO";
// java string compare while ignoring case
if (string1.equalsIgnoreCase(string2))
{
// this line WILL print
System.out.println("Ignoring case, the two strings are the same.")
}
选项 3:Java String 与 compareTo 方法的比较
还有第三种不太常见的方法来比较 Java 字符串,那就是使用 String 类 compareTo 方法。如果两个字符串完全相同,则 compareTo 方法将返回值 0(零)。下面是此字符串比较方法的快速示例:
String string1 = "foo bar";
String string2 = "foo bar";
// java string compare example
if (string1.compareTo(string2) == 0)
{
// this line WILL print
System.out.println("The two strings are the same.")
}
当我在 Java 中写这个相等的概念时,需要注意的是,Java 语言在 Java Object 基类中包含一个 equals 方法。每当您创建自己的对象并希望提供一种方法来查看对象的两个实例是否“相等”时,您应该在类中覆盖(并实现)此等于方法(就像 Java 语言在 String equals 方法中提供此相等/比较行为一样)。
你可能想看看这个 ==、.equals()、compareTo() 和 compare()
评论
运算符检查两个引用是否指向同一对象。 检查实际的字符串内容(值)。==
.equals()
请注意,该方法属于类(所有类的超类)。您需要根据类要求覆盖它,但对于 String,它已经实现,它会检查两个字符串是否具有相同的值。.equals()
Object
案例 1
String s1 = "Stack Overflow"; String s2 = "Stack Overflow"; s1 == s2; //true s1.equals(s2); //true
原因:创建的不带 null 的字符串文本存储在堆的 permgen 区域的 String 池中。因此,s1 和 s2 都指向池中的同一对象。
案例 2
String s1 = new String("Stack Overflow"); String s2 = new String("Stack Overflow"); s1 == s2; //false s1.equals(s2); //true
原因:如果使用关键字创建 String 对象,则会在堆上为其分配单独的空间。
new
如果该方法存在于类中,并且它应该检查对象状态的等效性!这意味着,对象的内容。而操作员应检查实际对象实例是否相同。equals()
java.lang.Object
==
例
考虑两个不同的参考变量,并且:str1
str2
str1 = new String("abc");
str2 = new String("abc");
如果您使用equals()
System.out.println((str1.equals(str2))?"TRUE":"FALSE");
您将获得输出,就像使用 .TRUE
==
System.out.println((str1==str2) ? "TRUE" : "FALSE");
现在你将获得 as 输出,因为两者都指向两个不同的对象,即使它们都共享相同的字符串内容。这是因为每次都会创建一个新对象。FALSE
str1
str2
new String()
在 Java 中,当运算符用于比较 2 个对象时,它会检查对象是否引用内存中的同一位置。换句话说,它会检查这两个对象名称是否基本上是对同一内存位置的引用。==
Java 类实际上覆盖了类中的默认实现——它覆盖了该方法,以便它只检查字符串的值,而不检查它们在内存中的位置。
这意味着,如果调用该方法来比较 2 个对象,则只要实际的字符序列相等,则认为两个对象相等。String
equals()
Object
equals()
String
运算符检查两个字符串是否完全相同的对象。
==
该方法检查两个字符串是否具有相同的值。
.equals()
评论
上一个:权威的 C++ 书籍指南和列表
评论
==
==
在某些时候会起作用,因为 java 有一个字符串池,它试图重用常用字符串的内存引用。但比较对象是相等的,而不是值相等的......您想要使用的正确用途也是如此。==
.equals()
"12"=="1"+2