此代码将字符串分隔为标记并将它们存储在字符串数组中,然后将变量与第一个主页进行比较...为什么它不起作用?
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");
}
}
答案 0 :(得分:545)
使用string.equals(Object other)
函数比较字符串,而不是==
运算符。
该函数检查字符串的实际内容,==
运算符检查对象的引用是否相等。请注意,字符串常量通常是“实例化”,这样两个具有相同值的常量实际上可以与==
进行比较,但最好不要依赖它。
if (usuario.equals(datos[0])) {
...
}
注意:比较是在'usuario'上完成的,因为你的代码中保证非空,尽管你仍然应该检查你在datos
数组中确实得到了一些标记,否则你会得到一个array-out-of-bounds异常。
答案 1 :(得分:514)
Jorman是一位成功的商人,拥有2间房屋。
但其他人不知道。
当你问麦迪逊街或伯克街的邻居时,这是他们唯一可以说的话:
单独使用住宅,很难确认它是同一个Jorman。由于它们是两个不同的地址,因此假设那些是两个不同的人是很自然的。
这就是运算符==
的行为方式。因此它会说datos[0]==usuario
为false,因为它只会比较地址。
如果我们派出调查员怎么办?我们知道它是同一个Jorman,但我们需要证明它。我们的侦探将密切关注所有物理方面。通过彻底的调查,代理人将能够得出结论是否是同一个人。让我们看看它是用Java术语发生的。
这是String的equals()
方法的源代码:
它逐字逐句地比较字符串,以得出它们确实相等的结论。
这就是字符串equals
方法的行为方式。所以datos[0].equals(usuario)
将返回true,因为它执行逻辑比较。
答案 2 :(得分:92)
值得注意的是,在某些情况下使用“==”运算符可能会导致预期结果,因为java处理字符串的方式 - 字符串文字被实现(请参阅{{1}在编译期间 - 所以当您在两个类中编写例如String.intern()
并将这些字符串与“==”进行比较时,您可以得到结果:true,这是根据specification预期的;当你比较相同的字符串(如果它们具有相同的值)时,第一个是字符串文字(即通过"hello world"
定义),第二个是在运行时构建的,即。使用像"i am string literal"
这样的“new”关键字,new String("i am string literal")
(相等)运算符返回false,因为它们都是==
类的不同实例。
只有正确的方法是使用String
- > .equals()
。 datos[0].equals(usuario)
仅当两个对象是同一个对象实例(即具有相同的内存地址)时才说明
更新:01.04.2013我更新了这篇帖子,因为下面的评论是正确的。最初我声明interning(String.intern)是JVM优化的副作用。虽然它肯定会节省内存资源(这就是我所说的“优化”)但它主要是语言的特征
答案 3 :(得分:33)
equals()
函数是Object
类的一种方法,应由程序员覆盖。 String
类会覆盖它以检查两个字符串是否相等,即内容而不是引用。
==
运算符检查两个对象的引用是否相同。
考虑一下程序
String abc = "Awesome" ;
String xyz = abc;
if(abc == xyz)
System.out.println("Refers to same string");
此处abc
和xyz
都指向相同的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");
此处abc
和xyz
是两个具有相同内容"Hello World"
的不同字符串。因此,(abc == xyz)
表达式为false
,其中(abc.equals(xyz))
为true
。
希望您了解==
和<Object>.equals()
感谢。
答案 4 :(得分:26)
而不是
datos[0] == usuario
使用
datos[0].equals(usuario)
==
比较变量的引用,其中.equals()
比较您想要的值。
答案 5 :(得分:23)
==
测试参考相等性。
.equals()
测试价值平等。
因此,如果您确实想要测试两个字符串是否具有相同的值,则应使用.equals()
(在少数情况下,您可以保证具有相同值的两个字符串将由同一对象表示例如:String
实习生。)
==
用于测试两个字符串是否相同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()
便宜得多(单指针比较而不是循环),因此,在适用的情况下(即你可以保证你是只处理实习字符串)它可以带来重要的性能提升。但是,这些情况很少见。
答案 6 :(得分:18)
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.
答案 7 :(得分: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");
}
答案 8 :(得分: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");
}
当第一行代码String str1 = "Hello world."
执行时,字符串\Hello world."
已创建,变量str1
引用它。当下一行代码由于优化而执行时,将不再创建另一个字符串"Hello world."
。变量str2
也指现有的""Hello world."
。
运算符==
检查两个对象的标识(两个变量是否指向同一对象)。由于str1
和str2
在内存中引用相同的字符串,因此它们彼此相同。方法equals
检查两个对象的相等性(两个对象是否具有相同的内容)。当然,str1
和str2
的内容相同。
当代码String str3 = new String("Hello world.")
执行时,会创建一个包含内容"Hello world."
的新字符串实例,并由变量str3
引用。然后再次创建另一个包含内容"Hello world."
的字符串实例,并将其引用
str4
。由于str3
和str4
指的是两个不同的实例,因此它们并不相同
内容相同。
因此,输出包含四行:
Str1 == str2
Str1 equals str2
Str3! = str4
Str3 equals str4
答案 9 :(得分:9)
你应该使用string equals来比较两个字符串的相等性,而不是运算符==,它只是比较引用。
答案 10 :(得分:7)
==
运算符比较Java中对象的引用。您可以使用字符串的equals
方法。
String s = "Test";
if(s.equals("Test"))
{
System.out.println("Equal");
}
答案 11 :(得分:6)
通常.equals
用于进行Object
比较,您需要验证两个Objects
是否具有相同的值。
==
用于参考比较(堆上的两个Objects
相同的Object
)&amp;检查Object
是否为空。它还用于比较基元类型的值。
答案 12 :(得分:6)
我知道这是一个老问题,但这是我看待它的方式(我觉得非常有用):
技术说明
在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()
的一个坚韧不拔的解释以及为什么它似乎是随机的。
答案 13 :(得分:6)
@ Melkhiah66您可以使用equals方法而不是'=='方法来检查相等性。
如果使用intern(),则它会检查对象是否在池中(如果存在)然后返回
等于其他不平等。 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
}
}
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
}
}
答案 14 :(得分:6)
==运算符是值的简单比较 对于对象引用,(值)是(引用)。因此,如果x和y引用相同的对象,则x == y将返回true。
答案 15 :(得分:6)
如果你要比较字符串的任何指定值,即原始字符串,“==”和.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
运算符...
答案 16 :(得分:4)
.equals()
将检查两个字符串是否具有相同的值并返回boolean
值,而==
运算符检查这两个字符串是否是同一个对象。< / p>
答案 17 :(得分:4)
有人在更高的帖子上说,==用于int和检查空值。 它也可以用于检查布尔运算和字符类型。
但要非常小心并仔细检查您是否使用了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
答案 18 :(得分:4)
a==b
比较参考,而不是值。 ==
与对象引用的使用通常限于以下内容:
比较参考是否为null
。
比较两个枚举值。这是有效的,因为每个enum
常量只有一个对象。
您想知道两个引用是否属于同一个对象
"a".equals("b")
比较相等的值。因为此方法是在Object
类中定义的,所以从中派生所有其他类,所以它会自动为每个类定义。但是,它不会对大多数类执行智能比较,除非该类重写它。对于大多数Java核心类,它已经以有意义的方式定义。如果没有为(用户)类定义它,它的行为与==
相同。
答案 19 :(得分:3)
使用Split而不是tokenizer,它肯定会提供精确的输出 例如:
string name="Harry";
string salary="25000";
string namsal="Harry 25000";
string[] s=namsal.split(" ");
for(int i=0;i<s.length;i++)
{
System.out.println(s[i]);
}
if(s[0].equals("Harry"))
{
System.out.println("Task Complete");
}
在此之后我相信你会得到更好的结果.....