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.")
}
Option 2: String comparison with the equalsIgnoreCase method
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.")
}
Option 3: Java String comparison with the compareTo method
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.")
}
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);
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)
// 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
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
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";
But beware of nulls!
== 处理 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));
23 回答
我同意zacherates的答案 .
但你可以做的是在你的非文字字符串上调用
intern()
.从zacherates示例:
如果你实习非文字字符串相等是
true
Java有一个String池,Java管理String对象的内存分配 . 见String Pools in Java
当您使用
==
运算符检查(比较)两个对象时,它会将地址相等性与字符串池进行比较 . 如果两个String对象具有相同的地址引用,则返回true
,否则返回false
. 但是,如果要比较两个String对象的内容,则必须覆盖equals
方法 .equals
实际上是Object类的方法,但它被重写到String类中,并给出了一个比较object对象内容的新定义 .但是请记住它尊重String的情况 . 如果您想要不区分大小写的比较,那么您必须使用String类的equalsIgnoreCase方法 .
让我们来看看:
在Java中,当 “==” 运算符用于比较2个对象时,它会检查对象是否引用内存中的相同位置 . 换句话说,它检查2个对象名称是否基本上是对同一内存位置的引用 .
Java String类实际上覆盖了Object类中的默认equals()实现 - 它覆盖了该方法,因此它只检查字符串的值,而不是它们在内存中的位置 . 这意味着如果调用equals()方法来比较2个String对象,那么只要实际的字符序列相等,两个对象就被认为是相等的 .
==
执行 reference 等式检查,无论2个对象(在本例中为字符串)是否引用内存中的同一对象 .equals()
方法将检查2个对象的 contents 或 states 是否相同 .显然
==
更快,但是如果你只是想知道2String
是否持有相同的文本,在许多情况下会(可能)给出错误的结果 .绝对建议使用
equals()
方法 .不要担心性能 . 有些事情要鼓励使用
String.equals()
:String.equals()
的实现首先检查引用相等性(使用==
),如果2个字符串通过引用相同,则不再执行进一步的计算!如果2个字符串引用不相同,
String.equals()
将接下来检查字符串的长度 . 这也是一个快速操作,因为String
类存储字符串的长度,不需要计算字符或代码点 . 如果长度不同,不再进行进一步检查,我们知道它们不能相等 .只有当我们到达这一点时才会实际比较2个字符串的内容,这将是一个简短的比较:如果我们找到不匹配的字符(在2中的相同位置),不会比较所有字符字符串),不会检查其他字符 .
完成所有操作后,即使我们保证字符串是实习生,使用
equals()
方法仍然不是人们可能认为的开销,绝对是推荐的方法 . 如果您想要有效的引用检查,那么使用枚举,语言规范和实现保证相同的枚举值将是同一个对象(通过引用) .==
比较对象的引用值,而java.lang.String
类中的equals()
方法比较String
对象(到另一个对象)的内容 .== compares object references in Java ,
String
对象也不例外 .For comparing the actual contents of objects (including String), one must use the equals method .
如果使用
==
对两个String
对象的比较结果是true
,那是因为String
对象被实现了,并且Java虚拟机有多个引用指向String
的同一个实例 . 我们不应期望将包含相同内容的一个String
对象与使用==
的另一个String
对象进行比较,以评估为true
.如果你像我一样,当我第一次开始使用Java时,我想使用“==”运算符来测试两个String实例是否相等,但无论好坏,这都不是在Java中执行它的正确方法 .
在本教程中,我将演示几种不同的正确比较Java字符串的方法,从我大多数时候使用的方法开始 . 在Java String比较教程的最后,我还将讨论为什么“==”运算符在比较Java字符串时不起作用 .
Option 1: Java String comparison with the equals method 大部分时间(可能是95%的时间)我将字符串与Java String类的equals方法进行比较,如下所示:
这个String equals方法查看两个Java字符串,如果它们包含完全相同的字符串,则它们被认为是相等的 .
使用equals方法查看快速字符串比较示例,如果运行以下测试,则两个字符串将不会被视为相等,因为字符不完全相同(字符的大小写不同):
但是,当两个字符串包含完全相同的字符串时,equals方法将返回true,如下例所示:
Option 2: String comparison with the equalsIgnoreCase method
在一些字符串比较测试中,您将要忽略字符串是大写还是小写 . 如果要以不区分大小写的方式测试字符串是否相等,请使用String类的equalsIgnoreCase方法,如下所示:
Option 3: Java String comparison with the compareTo method
还有第三种,不太常见比较Java字符串的方法,以及String类compareTo方法 . 如果两个字符串完全相同,则compareTo方法将返回值0(零) . 以下是此String比较方法的快速示例:
虽然我在Java中写这个相等的概念,但重要的是要注意Java语言在基础Java Object类中包含一个equals方法 . 每当您创建自己的对象并且想要提供一种方法来查看对象的两个实例是否“相等”时,您应该在类中覆盖(并实现)此equals方法(与Java语言提供的方式相同) String equals方法中的这种相等/比较行为) .
你可能想看一下这个==, .equals(), compareTo(), and compare()
功能:
测试:
我认为当你定义一个
String
时,你定义了一个对象 . 所以你需要使用.equals()
. 使用原始数据类型时,使用==
但使用String
(和任何对象),必须使用.equals()
.运算符==始终用于 object reference comparison ,而字符串类.equals()方法为 content comparison 重写:
保证所有对象都具有
.equals()
方法,因为Object包含一个返回布尔值的方法.equals()
. 如果需要进一步的定义定义,则覆盖此方法是子类的工作 . 没有它(即使用==
),仅在两个对象之间检查存储器地址是否相等 . String会覆盖此.equals()
方法,而不是使用内存地址,它会返回字符级别的字符串比较以获得相等性 .关键的一点是,字符串存储在一个块池中,因此一旦创建了一个字符串,它就永远存储在同一地址的程序中 . 字符串不会改变,它们是不可改变的 . 这就是为什么如果要进行大量的字符串处理,使用常规字符串连接是一个坏主意 . 相反,您将使用提供的
StringBuilder
类 . 记住指向这个字符串的指针可以改变,如果你有兴趣看看两个指针是否相同==
将是一个很好的方法 . 字符串本身没有 .==
测试引用相等性(它们是否是同一个对象) ..equals()
测试值的相等性(它们是否逻辑"equal") .Objects.equals()在调用
.equals()
之前检查null
,因此您不必(从JDK7开始,也可在Guava中使用) .String.contentEquals()将
String
的内容与任何CharSequence
(自Java 1.5以来可用)的内容进行比较 .因此,如果要测试两个字符串是否具有相同的值,您可能需要使用
Objects.equals()
.你几乎 always 想要使用
Objects.equals()
. 在 rare 情况下,您处理interned字符串 know ,您可以使用==
.来自JLS 3.10.5. String Literals:
类似的例子也可以在JLS 3.10.5-1中找到 .
确保你明白为什么 . 这是因为
==
比较仅比较参考;equals()
方法对内容进行逐字符比较 .当您为
a
和b
调用new时,每个人都会获得一个新的引用,该引用指向字符串表中的"foo"
. 引用不同,但内容相同 .您还可以使用
compareTo()
方法比较两个字符串 . 如果compareTo结果为0,则两个字符串相等,否则被比较的字符串不相等 .==
比较引用并且不比较实际的字符串 . 如果您确实使用new String(somestring).intern()
创建了每个字符串,则可以使用==
运算符来比较两个字符串,否则只能使用equals()或compareTo方法 .==
比较对象引用 ..equals()
比较字符串值 .有时
==
会给出比较字符串值的幻想,如下列情况:这是因为当您创建任何字符串文字时,JVM首先在字符串池中搜索该字面值,如果找到匹配项,则将为新字符串指定相同的引用 . 因此,我们得到:
(a==b) ===> true
但是,
==
在以下情况下失败:在这种情况下,对于
new String("test")
语句将在堆上创建新的String,并且该引用将被赋予b
,因此b
将在堆上给出引用,而不是在String池中 .现在
a
指向String池中的String,而b
指向堆上的String . 因此我们得到:if(a==b) ===> false.
虽然
.equals()
总是比较String的值,所以在两种情况下都给出了true:所以使用
.equals()
总是更好 .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实例 . 否则你会遇到错误 .
==
运算符检查两个字符串是否完全相同 ..equals()
方法将检查两个字符串是否具有相同的值 .==
测试对象引用,.equals()
测试字符串值 .有时它看起来好像
==
比较值,因为Java做了一些幕后的东西,以确保相同的内联字符串实际上是同一个对象 .例如:
But beware of nulls!
==
处理null
字符串很好,但从空字符串调用.equals()
将导致异常:因此,如果您知道
fooString1
可能为null,请通过写信告诉读者以下是更短的,但它不太明显,它检查null(来自Java 7):
如果
equals()
类中存在equals()
方法,则应检查对象状态的等效性!这意味着,对象的内容 . 期望==
运算符检查实际对象实例是否相同 .例
考虑两个不同的引用变量
str1
和str2
:如果您使用
equals()
如果使用
==
,您将获得TRUE
的输出 .现在您将获得
FALSE
作为输出,因为str1
和str2
指向两个不同的对象,即使它们都共享相同的字符串内容 . 这是因为new String()
每次都会创建一个新对象 .==
运算符检查两个引用是否指向同一对象 ..equals()
检查实际的字符串内容(值) .请注意,
.equals()
方法属于类Object
(所有类的超类) . 您需要根据类要求覆盖它,但对于String,它已经实现,并检查两个字符串是否具有相同的值 .原因:在没有null的情况下创建的字符串文字存储在堆的permgen区域的String池中 . 所以s1和s2都指向池中的同一个对象 .
原因:如果使用
new
关键字创建String对象,则会在堆上为其分配单独的空间 .是的,这很糟糕......
==
表示您的两个字符串引用完全相同 . 您可能听说过这种情况,因为Java保留了一个文字表(它确实如此),但情况并非总是如此 . 有些字符串以不同的方式加载,由其他字符串等构成,因此您必须这样做从不假设两个相同的字符串存储在同一位置 .Equals为您进行真正的比较 .
是的,
==
不适合比较字符串(任何对象,除非你知道它们是规范的) .==
只是比较对象引用 ..equals()
测试平等 . 对于Strings来说,他们经常发现,但总是不能保证 ..equals()
比较一个类中的数据(假设该函数已实现) .==
比较指针位置(对象在内存中的位置) .如果两个对象(不是关于PRIMITIVES的对话)指向SAME对象实例,则
==
返回true . 如果两个对象包含相同的数据.equals()
则返回true equals() Versus == in Java这可能对你有帮助 .