String.equals与==

fra*_*a66 515 java string

此代码将字符串分隔为标记并将它们存储在字符串数组中,然后将变量与第一个主页进行比较...为什么它不起作用?

public static void main(String...aArguments) throws IOException {

    String usuario = "Jorman";
    String password = "14988611";

    String strDatos = "Jorman 14988611";
    StringTokenizer tokens = new StringTokenizer(strDatos, " ");
    int nDatos = tokens.countTokens();
    String[] datos = new String[nDatos];
    int i = 0;

    while (tokens.hasMoreTokens()) {
        String str = tokens.nextToken();
        datos[i] = str;
        i++;
    }

    //System.out.println (usuario);

    if ((datos[0] == usuario)) {
        System.out.println("WORKING");
    }
}
Run Code Online (Sandbox Code Playgroud)

Aln*_*tak 553

使用该string.equals(Object other)函数比较字符串,而不是==运算符.

该函数检查字符串的实际内容,==操作员检查对象的引用是否相等.请注意,字符串常量通常是"实例化",这样可以实际比较具有相同值的两个常量==,但最好不要依赖它.

if (usuario.equals(datos[0])) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

注意:比较是在'usuario'上进行的,因为在代码中保证非null,尽管你仍然应该检查你是否确实在datos数组中得到了一些标记,否则你会得到一个数组超出范围的异常.

  • 甚至在java ==的某些情况下@mo可能会产生误导.Java缓存字符串,所以这样的东西会返回true.`String a ="Hello"; 字符串b ="你好"; a == b为真,即使人们通常期望结果为假. (50认同)
  • @mo:正如你在本例中所看到的那样,处理不同. (10认同)
  • @parasietje JLS保证多次出现的"Hello"(作为文字)引用相同的String对象.编译器不能用其他东西替换它. (10认同)
  • @JonTaylor您的示例与缓存无关.在java代码中键入"Hello"实际上会在类中创建一个匿名的静态String对象.如果您正在使用一个好的编译器,多次出现的"Hello"*可能*使用相同的静态String对象,但用"new String(new char [] {'H','替换"Hello"同样有效. e',...})` (6认同)
  • @trusktr你只能使用`=='来比较已被"实习"的字符串 - 通常是字符串常量. (4认同)
  • 使用`=='来比较字符串要非常小心,除非两者都用文字初始化`==`总是返回false.例如,这将打印**false**:`String a ="abc"; 字符串b ="abcd"; a + ="d"; System.out.println(a == b);` (4认同)

Jop*_*ops 522

认识乔曼

乔曼是一个成功的商人,有2个房子.

在此输入图像描述

但其他人不知道.

Jorman是一样的吗?

当你问麦迪逊街或伯克街的邻居时,这是他们唯一能说的话:

在此输入图像描述

单独使用住宅,很难确认它是同一个Jorman.由于它们是2个不同的地址,因此假设那些是2个不同的人是很自然的.

这就是操作员的==行为方式.所以它会说这datos[0]==usuario是假的,因为它只比较地址.

拯救调查员

如果我们派出调查员怎么办?我们知道它是同一个Jorman,但我们需要证明它.我们的侦探将密切关注所有物理方面.通过彻底的调查,代理人将能够得出结论是否是同一个人.让我们看看它是用Java术语发生的.

这是String equals()方法的源代码:

在此输入图像描述

它逐字逐句地比较字符串,以得出它们确实相等的结论.

这就是String equals方法的行为方式.因此,datos[0].equals(usuario)它将返回true,因为它执行逻辑比较.

  • 我喜欢直观的例子,这是我见过的最好的例子之一.新手程序员可以很容易地理解在幕后阅读本文的内容. (15认同)
  • 我实际上认为这个答案是_really_令人困惑,因为它将人的_name_与_person_self__混为一谈.它还将"平等"与"等同"混为一谈.`this == anObject`检查在语义上是_exactly_一个比较相同的两个对象(相等)的测试,因此根据定义它必须是等价的.`while`循环之后的最后一个`return true`确实_not_意味着我们有_same_"Jorman",这意味着两个实体共享相同的值(等价),这意味着_not_暗示相等.(Java` .ququals`方法在这方面被错误命名). (11认同)
  • @DavidT.你忘了检查指纹:) (3认同)
  • 最好的比喻!! (2认同)
  • `-1` 因为 [没有手绘红圈](http://meta.stackexchange.com/a/19775/255942) - 说真的,对于 Jorman 人来说,`+1`。 (2认同)

Mic*_*ard 93

值得注意的是,在某些情况下使用"=="运算符可以导致预期的结果,因为java处理字符串的方式 - String.intern()在编译期间字符串文字被嵌入(请参阅) - 所以当你"hello world"在两个类中编写时,将这些字符串与"=="进行比较,你可以得到结果:true,这是根据规范预期的; 当你比较相同的字符串(如果它们具有相同的值)时,第一个是字符串文字(即通过定义"i am string literal"),第二个是在运行时构建的,即.使用"new"关键字new String("i am string literal"),==(equality)运算符返回false,因为它们都是String类的不同实例.

只有正确的方法是使用.equals()- > datos[0].equals(usuario). ==只有当两个对象是同一个对象实例时才会说(即具有相同的内存地址)

更新:01.04.2013我更新了这篇帖子,因为下面的评论是正确的.最初我声明interning(String.intern)是JVM优化的副作用.虽然它肯定会节省内存资源(这就是我所说的"优化")但它主要是语言功能

  • 如果您的意思是JVM规范第2.3章"字符串文字,更一般地说,作为常量表达式值的字符串是"实例化",以便使用String.intern方法共享唯一实例.它是由jvm(根据规范)保证的,但对我来说这仍然意味着优化.这个AFAIK没有语义价值.另一方面,==具有语义"身份相等",方法equals()具有"对象相等",所以你应该遵守这一点而不依赖于jvm规范,这是jvm实现者的"指南",而不是开发人员(他们有Java)语言规范). (7认同)
  • 它实际上不仅仅是jvm优化的副作用,而且根本与编译器无关.根据Java VM规范保证所有类中的静态字符串(文字)的标识,并且与每个至少与Java 1.1兼容的VM一起使用. (6认同)
  • 文字,类名和类似物被实习以符合规范,这不仅仅是优化."xxx"总是=="xxx",这是语言设计的一部分而不是impl.细节/准则. (3认同)

Har*_*kar 35

equals()function是一个Object类的方法,应该被程序员覆盖.Stringclass重写它以检查两个字符串是否相等,即内容而不是引用.

== operator检查两个对象的引用是否相同.

考虑这些计划

String abc = "Awesome" ;
String xyz =  abc;

if(abc == xyz)
     System.out.println("Refers to same string");
Run Code Online (Sandbox Code Playgroud)

这里abcxyz,都指的是相同的String "Awesome".因此,表达(abc == xyz)true.

String abc = "Hello World";
String xyz = "Hello World";

if(abc == xyz)
    System.out.println("Refers to same string");
else
    System.out.println("Refers to different strings");

if(abc.equals(xyz))
     System.out.prinln("Contents of both strings are same");
else
     System.out.prinln("Contents of strings are different");
Run Code Online (Sandbox Code Playgroud)

这里abcxyz具有相同内容的两个不同的字符串"Hello World".因此这里的表达(abc == xyz)false其中作为(abc.equals(xyz))true.

希望你明白之间的差别==,并<Object>.equals()

谢谢.

  • 代码输出(在将prinln固定到println之后):引用相同的字符串,两个字符串的内容相同,即这里(abc == xyz)和(abc.equals(xyz))都是真的! (7认同)
  • 如上所述,这个答案是错误的.因为实习生优化机制,有时2个具有相同内容的字符串对象实际上只由一个对象表示.这种优化是可能的,因为字符串是不可变的 (6认同)

Bhu*_*ale 26

代替

datos[0] == usuario
Run Code Online (Sandbox Code Playgroud)

使用

datos[0].equals(usuario)
Run Code Online (Sandbox Code Playgroud)

==比较变量的引用,.equals()比较你想要的值.

  • 只要确保左侧不为空 (10认同)

Pun*_*hit 23

== 参考平等测试.

.equals() 测试价值平等.

因此,如果您确实想要测试两个字符串是否具有相同的值,则应使用.equals()(除非在少数几种情况下,您可以保证具有相同值的两个字符串将由同一对象表示,例如:Stringinterning).

==用于测试两个字符串是否相同Object.

// 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 

// concatenation of string literals happens at compile time resulting in same objects
"test" == "te" + "st"  ==> true

// but .substring() is invoked at runtime, generating distinct objects
"test" == "!test".substring(1) ==> false
Run Code Online (Sandbox Code Playgroud)

重要的是要注意==equals()(单指针比较而不是循环)便宜得多,因此,在适用的情况下(即,您可以保证您只处理实际的字符串),它可以提供重要的性能改进.但是,这些情况很少见.


Ani*_*kur 19

The == operator checks if the two references point to the same object or not.
.equals() checks for the actual string content (value).
Run Code Online (Sandbox Code Playgroud)

请注意,.equals()方法属于Object类(所有类的超类).您需要根据类要求覆盖它,但对于String,它已经实现,并检查两个字符串是否具有相同的值.

Case1)
String s1 = "Stack Overflow";
String s2 = "Stack Overflow";
s1 == s1;      // true
s1.equals(s2); // true
Reason: String literals created without null are stored in the string pool in the permgen area of the heap. So both s1 and s2 point to the same object in the pool.
Case2)
String s1 = new String("Stack Overflow");
String s2 = new String("Stack Overflow");
s1 == s2;      // false
s1.equals(s2); // true
Reason: If you create a String object using the `new` keyword a separate space is allocated to it on the heap.
Run Code Online (Sandbox Code Playgroud)


fin*_*nnw 12

如果intern()在将字符串插入数组之前调用字符串,它也会起作用.==当且仅当它们的值相等(equals().)时,实现的字符串是引用相等的()

public static void main (String... aArguments) throws IOException {

String usuario = "Jorman";
String password = "14988611";

String strDatos="Jorman 14988611";
StringTokenizer tokens=new StringTokenizer(strDatos, " ");
int nDatos=tokens.countTokens();
String[] datos=new String[nDatos];
int i=0;

while(tokens.hasMoreTokens()) {
    String str=tokens.nextToken();
    datos[i]= str.intern();            
    i++;
}

//System.out.println (usuario);

if(datos[0]==usuario) {  
     System.out.println ("WORKING");    
}
Run Code Online (Sandbox Code Playgroud)


Har*_* He 11

让我们分析以下Java,以了解字符串的身份和相等性:

public static void testEquality(){
    String str1 = "Hello world.";
    String str2 = "Hello world.";

    if (str1 == str2)
        System.out.print("str1 == str2\n");
    else
        System.out.print("str1 != str2\n");

    if(str1.equals(str2))
        System.out.print("str1 equals to str2\n");
    else
        System.out.print("str1 doesn't equal to str2\n");

    String str3 = new String("Hello world.");
    String str4 = new String("Hello world.");

    if (str3 == str4)
        System.out.print("str3 == str4\n");
    else
        System.out.print("str3 != str4\n");

    if(str3.equals(str4))
        System.out.print("str3 equals to str4\n");
    else
        System.out.print("str3 doesn't equal to str4\n");
}
Run Code Online (Sandbox Code Playgroud)

当第一行代码String str1 = "Hello world."执行时,\Hello world." 会创建一个字符串,变量str1引用它."Hello world."由于优化,下一行代码执行时,不会再次创建另一个字符串.变量str2也指现有的""Hello world.".

运算符==检查两个对象的标识(两个变量是否指向同一对象).由于str1并且str2在内存中引用相同的字符串,因此它们彼此相同.该方法equals检查两个对象的相等性(两个对象是否具有相同的内容).当然,内容str1str2是一样的.

代码String str3 = new String("Hello world.")执行时,"Hello world."会创建一个包含内容的字符串的新实例,并由变量引用str3.然后"Hello world."再次创建另一个带有内容的字符串实例,并引用它 str4.由于str3并且str4引用两个不同的实例,它们不相同,但它们的内容相同.

因此,输出包含四行:

Str1 == str2

Str1 equals str2

Str3! = str4

Str3 equals str4
Run Code Online (Sandbox Code Playgroud)


Mic*_*ent 9

你应该使用字符串equals比较两个字符串的相等性,而不是operator ==它只是比较引用.


小智 7

==运算符比较Java中对象的引用.你可以使用string的equals方法.

String s = "Test";
if(s.equals("Test"))
{
    System.out.println("Equal");
}
Run Code Online (Sandbox Code Playgroud)


mre*_*nia 6

如果你要比较字符串的任何指定值,即原始字符串,"=="和.equals都可以,但对于新的字符串对象,你应该只使用.equals,这里"=="将不起作用.

例:

String a = "name";

String b = "name";
Run Code Online (Sandbox Code Playgroud)

if(a == b) 并且(a.equals(b))将返回true.

String a = new String("a");
Run Code Online (Sandbox Code Playgroud)

在这种情况下if(a == b)将返回false

所以最好使用.equals运营商......


小智 6

通常.equals用于Object比较,您要验证两者Objects是否具有相同的值.

==用于参考比较(两个ObjectsObject堆上是相同的)并检查是否Object为null.它还用于比较基元类型的值.


eng*_*ngy 6

==运算符是值的简单比较.
对于对象引用,(值)是(引用).因此,如果x和y引用相同的对象,则x == y将返回true.


tin*_*iry 6

@ Melkhiah66您可以使用equals方法而不是'=='方法来检查相等性.如果你使用intern()然后它检查对象是否在池中如果存在然后返回等于else不等.equals方法在内部使用hashcode并获得所需的结果.

public class Demo
{
  public static void main(String[] args)
  {
              String str1 = "Jorman 14988611";
    String str2 = new StringBuffer("Jorman").append(" 14988611").toString();
    String str3 = str2.intern();
    System.out.println("str1 == str2 " + (str1 == str2));           //gives false
    System.out.println("str1 == str3 " + (str1 == str3));           //gives true
    System.out.println("str1 equals str2 " + (str1.equals(str2)));  //gives true
    System.out.println("str1 equals str3 " + (str1.equals(str3)));  //gives true
  }
}
Run Code Online (Sandbox Code Playgroud)


Rae*_*kye 6

我知道这是一个老问题,但这是我看待它的方式(我觉得非常有用):


技术说明

在Java中,所有变量都是基本类型引用.

(如果你需要知道引用是什么:"对象变量"只是对象的指针.所以Object something = ...,有些东西实际上是内存中的一个地址(一个数字).)

==比较确切的值.因此,它比较原始值是否相同,或者引用(地址)是否相同.这就是为什么==经常不能用于字符串; 字符串是对象,==如果地址在内存中相同,则对两个字符串变量进行比较,正如其他人指出的那样..equals()调用对象的比较方法,它将比较引用指向的实际对象.在字符串的情况下,它比较每个字符,看它们是否相等.


有趣的部分:

那么为什么==有时候为Strings返回呢?请注意,字符串是不可变的.在您的代码中,如果您这样做

String foo = "hi";
String bar = "hi";
Run Code Online (Sandbox Code Playgroud)

由于字符串是不可变的(当你调用.trim()或者某种东西时,它产生一个新的字符串,而不是修改内存中指向的原始对象),你实际上并不需要两个不同的String("hi")对象.如果编译器是智能的,则字节码将读取为仅生成一个String("hi")对象.所以,如果你这样做

if (foo == bar) ...
Run Code Online (Sandbox Code Playgroud)

之后,他们指向同一个对象,并将返回true.但你很少打算这样做.相反,你要求用户输入,这是在内存的不同部分等创建新的字符串等.

注意:如果你做了类似baz = new String(bar)的事情,编译器可能仍然认为它们是相同的.但重点是当编译器看到文字字符串时,它可以轻松地优化相同的字符串.

我不知道它在运行时是如何工作的,但我假设JVM没有保存"活字符串"列表并检查是否存在相同的字符串.(例如,如果您读取一行输入两次,并且用户输入两次相同的输入,则不会检查第二个输入字符串是否与第一个相同,并将它们指向同一个存储器).它会节省一些堆内存,但它的开销是不可忽视的.同样,关键是编译器很容易优化文字字符串.

在那里你有它...对于==对比的粗略解释.equals()以及为什么它似乎是随机的.