String.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; i++; } //System.out.println (usuario); if ((datos[0] == usuario)) { System.out.println("WORKING"); } } 

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

该函数检查字符串的实际内容, ==运算符检查对象的引用是否相等。 请注意,字符串常量通常是“实例化”,这样两个具有相同值的常量实际上可以与==进行比较,但最好不要依赖它。

 if (usuario.equals(datos[0])) { ... } 

注意:比较是在’usuario’上完成的,因为在你的代码中保证非null,尽管你仍然应该检查你在datosarrays中确实得到了一些标记,否则你会得到一个数组越界例外。

认识乔曼

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

在此处输入图像描述

但其他人不知道。

Jorman是一样的吗?

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

在此处输入图像描述

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

这就是运算符==行为方式。 所以它会说datos[0]==usuario是假的,因为它只比较地址

救援调查员

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

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

在此处输入图像描述

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

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

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

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

更新 :01.04.2013我更新了这篇post,因为下面的评论是正确的。 最初我声明interning(String.intern)是JVM优化的副作用。 虽然它确实节省了内存资源(这就是我所说的“优化”),但它主要是语言function

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

==运算符检查两个对象的引用是否相同。

考虑这些计划

 String abc = "Awesome" ; String xyz = abc; if(abc == xyz) System.out.println("Refers to same string"); 

这里的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"); 

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

希望你理解==.equals()之间的区别

谢谢。

代替

 datos[0] == usuario 

使用

 datos[0].equals(usuario) 

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

==测试参考相等性。

.equals()测试值的相等性。

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

==用于测试两个字符串是否是同一个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 

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

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

请注意,.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. 

如果在将字符串插入数组之前调用字符串上的intern() ,它也会起作用。 当且仅当它们是值相等( equals()字符串是引用相等的( == 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"); } 

让我们分析以下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"); } 

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

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

当代码String str3 = new String("Hello world.")执行时,一个新的字符串实例,其内容为"Hello world." 已创建,它由变量str3 。 然后是另一个包含内容"Hello world."的字符串实例"Hello world." 再次创建,并由str4 。 由于str3str4指的是两个不同的实例,它们不相同,但它们的内容相同。

因此,输出包含四行:

 Str1 == str2 Str1 equals str2 Str3! = str4 Str3 equals str4 

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

==运算符比较Java中对象的引用。 您可以使用字符串的equals方法。

 String s = "Test"; if(s.equals("Test")) { System.out.println("Equal"); } 

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

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


技术说明

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

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

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


有趣的部分

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

 String foo = "hi"; String bar = "hi"; 

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

 if (foo == bar) ... 

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

注意 :如果你执行类似baz = new String(bar)的操作,编译器可能仍然会发现它们是相同的。 但重点是当编译器看到文字字符串时,它可以轻松地优化相同的字符串。

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

你有它……对==.equals()的粗略解释以及为什么它似乎是随机的。

@ 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 } } 

通常.equals用于Object比较,您要在其中validation两个Objects是否具有相同的值。

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

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

例:

 String a = "name"; String b = "name"; 

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

 String a = new String("a"); 

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

所以最好使用.equals运算符……

.equals()将检查两个字符串是否具有相同的值并返回boolean值,而==运算符检查两个字符串是否是同一个对象。

有人在更高的post上说,==用于int和检查空值。 它还可以用于检查布尔运算和char类型。

但要非常小心并仔细检查您是否使用了char而不是String。 例如

  String strType = "a"; char charType = 'a'; 

对于字符串,你会检查这是正确的

  if(strType.equals("a") do something 

  if(charType.equals('a') do something else 

如果不正确,您需要执行以下操作

  if(charType == 'a') do something else 

a==b

比较参考,而不是值。 使用==和对象引用通常限于以下内容:

  1. 比较以查看引用是否为null

  2. 比较两个枚举值。 这是有效的,因为每个enum常量只有一个对象。

  3. 您想知道两个引用是否属于同一个对象

"a".equals("b")

比较相等的值。 因为此方法是在Object类中定义的,所以从中派生所有其他类,所以它会自动为每个类定义。 但是,它不会对大多数类执行智能比较,除非该类重写它。 对于大多数Java核心类,它已经以有意义的方式定义。 如果没有为(用户)类定义它,它的行为与==相同。

使用Split而不是tokenizer,它肯定会为Eg提供精确的输出:

 string name="Harry"; string salary="25000"; string namsal="Harry 25000"; string[] s=namsal.split(" "); for(int i=0;i 

在此之后我相信你会得到更好的结果.....