tags:

views:

2744

answers:

6

This code separates a string into tokens and stores them in an array of strings, and then compares a variable with the first home ... why isn't it working?

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");    
}
+11  A: 

Use the String.equals(String other) function to compare strings, not the == operator.

The function checks the actual contents of the string, the == operator checks whether the references to the objects are equal.

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

nb: the compare is done on 'usuario' because that's guaranteed non-null in your code, although you should still check that you've actually got some tokens in the datos array otherwise you'll get an array-out-of-bounds exception.

Alnitak
+6  A: 

Instead of

datos[0] == usuario

use

datos[0].equals(usuario)

== compares the reference of the variable where .equals() compares the values which is what you want.

Bhushan
just make sure the left side isn't null
Steve Kuo
+2  A: 

You should use string equals to compare two strings for equality, not operator == which just compares the references.

Michael Barth
+5  A: 

It's good to notice that in some cases use of "==" operator can lead to the expected result, because the way how JVM handling strings - string literals are interned (see String.intern()) - so when you write for example "hello world" in two classes and compare those strings with "==" you could get result: true, which is expected, but it's only side effect of jvm optimizations; when you compare same strings (linguistically) when the first is string literal (ie. defined through "string") and second is constructed through "new" keyword like new String("string") using of == (equality operator) returns false, because both of them are different instances of String class.

Only right way is using ".equals()" -> datos[0].equals(usuario). "==" says only if two objects are the same instance of object (ie. have same memory address)

Michal Bernhard
It's actually not just a side effect of jvm optimization and has nothing to do with the compiler at all. The identity of static strings (literals) across all classes is guaranteed according to the Java VM Specification and works with every VM that is at least Java 1.1 compatible.
x4u
Well you are right. I updated my post. I hope it's ok now. Please let me know.
Michal Bernhard
+1  A: 

For anyone who needs more proves:

String abcdString = "abcd";
char[] abcdArray = {'a','b','c','d'};
String abcdArrayToString = new String(abcdArray);
System.out.println("abcdString: "+abcdString);
System.out.println("abcdArrayToString: "+abcdArrayToString);
System.out.println("abcdString == abcdArrayToString = "+(abcdString == abcdArrayToString));
System.out.println("abcdString.equals(abcdArrayToString) = "+abcdString.equals(abcdArrayToString));
+1  A: 

It will also work if you call intern() on the string before inserting it into the array. Interned strings are reference-equal (==) if and only if the are value-equal (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");    
}
finnw