如何比较 Java 中的字符串?

共23个回答,已解决, 标签: java string equality

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

== 糟糕吗?什么时候应该使用, 不应该使用?有什么区别?

第1个答案(采用)

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

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

对象. () 在 null 调用之前进行检查, .equals() 这样您就不必执行 (jdk7 提供, 也可在guava中使用)。

字符串. 内容相等 () 将任何内容 String 的内容与任何 CharSequence 内容的内容进行比较 (自 java 1.5 以来可用)。

因此, 如果要测试两个字符串是否具有与您可能要使用的相同值. 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 中也可以找到类似的示例。

第2个答案

==测试对象引用, .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 (从 Java 7) 的情况不太明显:

System.out.print(Objects.equals(fooString1, "bar"));
第3个答案

==比较对象引用。

.equals()比较字符串值。

有时 == 会给出比较字符串值的错觉, 如以下情况所示:

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

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

(a = = b) = = = > true

                       String Pool
     <-----------------a>

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

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

在这种情况下 new String("test") , 语句将在堆上创建新的 string, 并将向其提供该引用 b , 因此 b 将在堆上而不是在 string 池中提供引用。

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

如果 (a = b) = = = > false。

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

第4个答案

==运算符检查这两个字符串是否完全相同的对象。

.equals() 方法将检查两个字符串是否具有相同的值。

第5个答案

Java 中的字符串是不可变的。这意味着, 每当您尝试更改/修改字符串时, 都会得到一个新实例。不能更改原始字符串。这样做是为了可以缓存这些字符串实例。一个典型的程序包含大量的字符串引用, 缓存这些实例可以减少内存占用, 并提高程序的性能。

使用 = = 运算符进行字符串比较时, 您不是在比较字符串的内容, 而是实际比较内存地址。如果他们都是平等的, 否则会返回真假。而字符串中的相等比较字符串内容。

因此, 问题是, 如果所有字符串都缓存在系统中, 为什么 == 返回 false, 而等于返回 true?嗯, 这是有可能的。如果您创建了一个新字符串, 就像 String str = new String("Testing") 您最终在缓存中创建了一个新字符串, 即使缓存已经包含具有相同内容的字符串。总之 "MyString" == new String("MyString") , 总会回归虚假。

Java 还讨论了可在字符串上使用的函数实习生 (), 使其成为缓存的一部分, 因此 "MyString" == new String("MyString").intern() 将返回 true。

注意: = = 运算符比等于快得多, 因为您比较的是两个内存地址, 但您需要确保代码不会在代码中创建新的 String 实例。否则, 您将遇到错误。

第6个答案
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 ab 时, 每个引用都会得到一个指向 "foo" 字符串表中的新引用。 引用是不同的, 但内容是相同的。

第7个答案

是啊, 这很糟糕..。

==表示两个字符串引用完全相同。您可能听说过这种情况, 因为 Java 保留了某种文字表 (它确实如此), 但情况并非总是如此。某些字符串是以不同的方式加载的, 由其他字符串等构造, 因此您绝不能假定两个相同的字符串存储在同一位置。

等于为你做真正的比较。

第8个答案

是的, == 不适合比较字符串 (任何对象真的, 除非你知道它们是规范的)。 ==只是比较对象引用。 .equals()平等的考验。对于字符串来说, 它们通常是一样的, 但正如你所发现的, 这并不总是可以保证的。

第9个答案

Java 有一个字符串池, 在该池中, Java 管理字符串对象的内存分配。请参阅 java 中的字符串池

当您使用运算符检查 (比较) 两个对象时, == 它将地址相等性与字符串池进行比较。如果两个 String 对象具有相同的地址引用, 则它将返回 true , 否则. false但是, 如果要比较两个 String 对象的内容, 则必须重写该 equals 方法。

equals实际上是 Object 类的方法, 但它被重写到 String 类中, 并给出了一个比较对象内容的新定义。

Example:
    stringObjectOne.equals(stringObjectTwo);

但请注意, 它尊重字符串的情况。如果需要不区分大小写的比较, 则必须选择 String 类的 Equal 不必注意用例方法。

我看看:

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
第10个答案

== 比较 java 中的对象引用, 这对于对象也不例外 String

若要比较对象 (包括) 的实际内容 String , 必须使用该 equals 方法

如果对使用的两个 String 对象进行比较 == true , 那是因为 String 这些对象是被锁定的, 并且 java 虚拟机有多个引用指向同一个实例 String 。人们不应该期望将 String 一个包含与另一个对象相同内容的对象进行 String == 比较, 以计算为 true

第11个答案

我同意 zacherates 的回答。

但你能做的是调用 intern() 你的非文字字符串。

从 zacher 茨除示例:

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

如果您实习非文字字符串相等是true

new String("test").intern() == "test" ==> true
第12个答案

.equals()比较类中的数据 (假设函数已实现)。 ==比较指针位置 (对象在内存中的位置)。

==如果两个对象 (不谈论 PRIIMITVES) 指向相同的对象实例, 则返回 true。 .equals()如果两个对象包含相同的数据 equals()== java 中, 则返回 true

这可能对你有帮助。

第13个答案

==执行引用相等性检查, 是否两个对象 (本例中为字符串) 引用内存中的同一对象。

equals() 方法将检查 2 个对象的内容状态是否相同。

显然 == 是更快的, 但如果你只想判断我们是否持有相同的文本, 在很多情况下都会给出 String 错误的结果。

肯定 equals() 使用的方法是推荐的。

不要担心性能。鼓励使用的一些事项 String.equals() :

  1. 实现 String.equals() 对引用相等性 (使用) 的第一次检查 == , 如果两个字符串通过引用是相同的, 则不会执行进一步的计算!
  2. 如果 2 个字符串引用不相同, String.equals() 则下一步将检查字符串的长度。这也是一个快速操作, 因为 String 类存储字符串的长度, 不需要计算字符或代码点。如果长度不同, 则不执行进一步检查, 我们知道它们不能相等。
  3. 只有我们走到现在, 才会实际比较 2 个字符串的内容, 这将是一个短手比较: 不是所有的字符都会被比较, 如果我们发现一个不匹配的字符 (在两个字符串中的同一位置), 没有更多的字符将是可检查卡。

当一切都说出来、做完的时候, 即使我们有保证字符串是实习生, 使用这种 equals() 方法仍然不是人们可能认为的开销, 绝对是推荐的方式。如果要进行有效的引用检查, 请使用由语言规范和实现保证相同枚举值将是相同对象的枚举 (通过引用)。

第14个答案

如果您和我一样, 当我刚开始使用 Java 时, 我想使用 "= =" 运算符来测试两个 String 实例是否相等, 但不管是好是坏, 这都不是在 Java 中执行此操作的正确方法。

在本教程中, 我将演示几种正确比较 Java 字符串的不同方法, 从我大部分时间使用的方法开始。在本 Java 字符串比较教程的末尾, 我还将讨论为什么 "= =" 运算符在比较 Java 字符串时不起作用。

选项 1: 与相等方法的 Java 字符串比较 大多数情况下 (可能 95% 的时间), 我将字符串与 Java String 类的相等方法进行比较, 如下所示:

if (string1.equals(string2))

此 String 等号方法查看两个 Java 字符串, 如果它们包含完全相同的字符串, 则认为它们相等。

查看具有相等方法的快速 String 比较示例, 如果运行以下测试, 则两个字符串将不被视为相等, 因为字符不完全相同 (字符的大小写不同):

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.")
}

但是, 当两个字符串包含完全相同的字符串时, 等于方法将返回 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: 与等价 Nornoresase 方法的字符串比较

在某些字符串比较测试中, 您需要忽略字符串是大写还是小写。当您要以这种不区分大小写的方式测试字符串的相等性时, 请使用 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 字符串与比较到方法的比较

还有第三种比较 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 类中包含了一个相等的方法。每当您创建自己的对象, 并且希望提供一种方法来查看对象的两个实例是否 "相等" 时, 就应该重写 (并实现) 这等于类中的方法 (就像 Java 语言提供这种相等的比较一样)行为在字符串等于方法)。

您可能需要查看此= =, 等于 (), 比较 (), 并比较 ()

第15个答案

功能:

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);

    < 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);
第16个答案

==运算符检查两个引用是否指向同一个对象. 检查 .equals() 实际的字符串内容 (值)。

请注意, 该 .equals() 方法属于类 Object (所有类的超级类)。您需要按照类要求重写它, 但对于 String, 它已经实现, 它检查两个字符串是否具有相同的值。

  • 案例 1

    String s1 = "Stack Overflow";
    String s2 = "Stack Overflow";
    s1 == s2;      //true
    s1.equals(s2); //true
    

    原因: 在没有 null 的情况下创建的字符串文本存储在堆的 permgen 区域中的字符串池中。因此, s1 和 s1 都指向池中的同一对象。

  • 案例 2

    String s1 = new String("Stack Overflow");
    String s2 = new String("Stack Overflow");
    s1 == s2;      //false
    s1.equals(s2); //true
    

    原因: 如果使用关键字创建 String 对象, new 则会在堆上为其分配单独的空间。

第17个答案

==比较对象的参考值, 而 equals() 类中存在的方法 java.lang.String String 比较对象的内容 (与另一个对象)。

第18个答案

我认为, 当您 String 定义一个对象。所以你需要使用 .equals() 。当您使用原始数据类型时, == 您使用, 但 String 与 (和任何对象) 一起使用时, 您必须使用 .equals()

第19个答案

如果该 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");

现在, 您将获得 FALSE 输出, 因为这两个 str1 str2 对象都指向两个不同的对象, 即使它们都共享相同的字符串内容。这是因为 new String() 每次都创建一个新对象。

第20个答案

运算符= = 始终用于对象引用比较, 而 string类. 相等 ()方法被重写以进行内容比较:

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)
第21个答案

保证所有对象都 .equals() 有一个方法, 因为 object 包含一个 .equals() 方法, 该方法返回一个布尔值。如果需要进一步的定义, 重写此方法是子类的作业。如果没有它 (即使用 == ), 则只在两个对象之间检查内存地址以确保相等。字符串重写此 .equals() 方法, 而不是使用内存地址, 它返回字符级别的字符串的比较是否相等。

一个关键的注意是, 字符串存储在一个块池中, 因此一旦创建了字符串, 它就永远存储在同一地址的程序中。字符串不会改变, 它们是不可变的。这就是为什么如果要执行大量的字符串处理, 则使用常规字符串连接是一个坏主意。相反, 您将使用 StringBuilder 提供的类。请记住, 指向此字符串的指针可能会更改, 如果您有兴趣查看两个指针是否相同 == , 将是一个很好的方法。字符串本身并不如此。

第22个答案

您还可以使用该 compareTo() 方法比较两个字符串。如果比较到结果为 0, 则两个字符串相等, 否则所比较的字符串不相等。

==比较引用, 而不比较实际字符串。如果确实使用每个字符串创建了, new String(somestring).intern() 则可以使用 == 运算符比较两个字符串, 否则等于 () 或 compareto 方法只能使用。

第23个答案

在 Java 中,当使用 "= =" 运算符比较2 个对象时, 它会检查这些对象是否引用内存中的同一位置。换句话说, 它检查 2 个对象名称是否基本上是对同一内存位置的引用。

Java String 类实际上重写 object 类中的默认等于 () 实现, 并覆盖该方法, 以便它只检查字符串的值, 而不检查它们在内存中的位置。 这意味着, 如果调用同样 () 方法来比较 2 个 String 对象, 则只要实际的字符序列相等, 这两个对象就被视为相等。

==运算符检查两个字符串是否完全相同的对象。

.equals()方法检查两个字符串是否具有相同的值。

相关问题

Java 是 "逐项传递" 还是 "按值传递"? 如何比较 Java 中的字符串? 什么是 Null Pointerexception, 我如何修复它? 删除字符串中的特定单词 C # 中如何在字符串末尾退出 while 循环 为什么比较字符串 0 (n),但比较数字 0 (1)? 为什么 Javascript 将 5 = = 8 等同为 true?