Ce code sépare une chaîne en jetons et les stocke dans un tableau de chaînes, puis compare une variable à la première maison ... pourquoi ne fonctionne-t-il pas?
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");
}
}
Utilisez la fonction string.equals(Object other)
pour comparer des chaînes, et non l'opérateur ==
.
La fonction vérifie le contenu réel de la chaîne, l'opérateur ==
vérifie si les références aux objets sont égales. Notez que les constantes de chaîne sont généralement "internées", de sorte que deux constantes avec la même valeur peuvent en réalité être comparées avec ==
, mais il est préférable de ne pas compter sur cela.
if (usuario.equals(datos[0])) {
...
}
NB: la comparaison est faite sur 'usuario' car c'est garanti non-nul dans votre code, bien que vous deviez quand même vérifier que vous avez bien quelques jetons dans le tableau datos
sinon vous aurez un tableau exception-of-bounds.
Jorman est un homme d'affaires prospère et possède 2 maisons.
Mais d'autres ne le savent pas.
Lorsque vous interrogez des voisins des rues Madison ou Burke, c'est la seule chose qu'ils peuvent dire:
En utilisant la résidence seule, il est difficile de confirmer que c'est le même Jorman. Comme il s'agit de deux adresses différentes, il est naturel de supposer qu'il s'agit de deux personnes différentes.
C’est comme ça que l’opérateur ==
se comporte. On dira donc que datos[0]==usuario
est faux, car il ne fait que comparer les adresses .
Et si on envoyait un enquêteur? Nous savons que c'est le même Jorman, mais nous devons le prouver. Notre détective examinera de près tous les aspects physiques. Avec une enquête approfondie, l'agent sera en mesure de déterminer s'il s'agit de la même personne ou non. Voyons que cela se passe en Java termes.
Voici le code source de la méthode equals()
de String:
Il compare le caractère de Strings par caractère, afin de conclure à leur égalité.
C'est comme ça que la méthode String equals
se comporte. Donc datos[0].equals(usuario)
retournera true, car elle effectuera une comparaison logique .
Il est bon de noter que dans certains cas, l'utilisation de l'opérateur "==" peut conduire au résultat attendu, car la manière dont Java traite les chaînes - littéraux de chaîne sont internés (voir String.intern()
) lors de la compilation - ainsi, lorsque vous écrivez par exemple "hello world"
dans deux classes et comparez ces chaînes avec "==", vous pouvez obtenir le résultat: true, ce qui est attendu selon spécification ; lorsque vous comparez les mêmes chaînes (si elles ont la même valeur) lorsque la première est littérale (c'est-à-dire définie via "i am string literal"
) et que la seconde est construite au moment de l'exécution, c'est-à-dire. Avec le mot-clé "new" tel que new String("i am string literal")
, l'opérateur ==
(égalité) renvoie false, car ils sont tous deux des instances différentes de la classe String
.
La seule façon correcte d'utiliser .equals()
-> datos[0].equals(usuario)
. ==
ne dit que si deux objets sont la même instance d'objet (c'est-à-dire qu'ils ont la même adresse mémoire)
Mise à jour : 01.04.2013 J'ai mis à jour ce message en raison de commentaires ci-dessous qui sont en quelque sorte corrects. A l'origine, j'avais déclaré que interning (String.intern) était un effet secondaire de l'optimisation de la machine virtuelle Java. Bien que cela économise certainement des ressources de mémoire (ce que je voulais dire par "optimisation"), il est principalement caractéristique du langage
La fonction equals()
est une méthode de la classe Object
qui doit être remplacée par le programmeur. String
class la remplace pour vérifier si deux chaînes sont égales, c'est-à-dire contenu et non référencé.
==
l'opérateur vérifie si les références des deux objets sont identiques.
Considérez les programmes
String abc = "Awesome" ;
String xyz = abc;
if(abc == xyz)
System.out.println("Refers to same string");
Ici, abc
et xyz
désignent tous deux le même String
"Awesome"
. Par conséquent, l'expression (abc == xyz)
est 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");
Ici abc
et xyz
sont deux chaînes différentes ayant le même contenu "Hello World"
. D'où ici l'expression (abc == xyz)
est false
où en tant que (abc.equals(xyz))
est true
.
J'espère que vous avez compris la différence entre ==
et <Object>.equals()
Merci.
Au lieu de
datos[0] == usuario
utilisation
datos[0].equals(usuario)
==
compare la référence de la variable où .equals()
compare les valeurs souhaitées.
==
teste l'égalité de référence.
.equals()
teste l'égalité des valeurs.
Par conséquent, si vous voulez réellement vérifier si deux chaînes ont la même valeur, vous devez utiliser .equals()
(sauf dans quelques cas où vous pouvez garantir que deux chaînes ayant la même valeur seront représentées par le même objet, par exemple: String
interning).
==
sert à vérifier si deux chaînes sont identiques 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
Il est important de noter que ==
est beaucoup moins cher que equals()
(une comparaison de pointeur unique au lieu d'une boucle). Par conséquent, dans les cas où cela est applicable (vous pouvez donc garantir que vous ne traitez chaînes internes) peut présenter une amélioration importante de la performance. Cependant, ces situations sont rares.
The == operator checks if the two references point to the same object or not.
.equals() checks for the actual string content (value).
Notez que la méthode .equals () appartient à la classe Object (super classe de toutes les classes). Vous devez le remplacer conformément aux exigences de votre classe, mais pour String, il est déjà implémenté et il vérifie si deux chaînes ont la même valeur ou non.
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.
Cela fonctionnera également si vous appelez intern()
sur la chaîne avant de l'insérer dans le tableau. Les chaînes internées sont égales en référence (==
) si et seulement si elles sont égales en valeur (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");
}
Analysons le Java suivant, pour comprendre l'identité et l'égalité des chaînes:
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");
}
Lorsque la première ligne du code String str1 = "Hello world."
est exécutée, une chaîne \Hello world."
est créée et la variable str1
s'y réfère. Une autre chaîne "Hello world."
ne sera pas créée à nouveau lorsque la ligne de code suivante sera exécutée pour des raisons d'optimisation. La variable str2
fait également référence au ""Hello world."
existant.
L'opérateur ==
vérifie l'identité de deux objets (si deux variables se rapportent au même objet). Puisque str1
et str2
font référence à la même chaîne en mémoire, elles sont identiques. La méthode equals
vérifie l'égalité de deux objets (si deux objets ont le même contenu). Bien entendu, le contenu de str1
et str2
est identique.
Lorsque le code String str3 = new String("Hello world.")
s'exécute, une nouvelle instance de chaîne avec un contenu "Hello world."
est créée et elle est désignée par la variable str3
. Et puis une autre instance de chaîne avec le contenu "Hello world."
est créée à nouveau et désignée par str4
. Puisque str3
et str4
font référence à deux instances différentes, elles ne sont pas identiques, mais leur contenu est identique.
Par conséquent, la sortie contient quatre lignes:
Str1 == str2
Str1 equals str2
Str3! = str4
Str3 equals str4
Vous devez utiliser chaîne égale pour comparer deux chaînes pour l’égalité, et non opérateur == qui compare simplement les références.
==
l'opérateur compare la référence d'un objet en Java. Vous pouvez utiliser la méthode equals
de string.
String s = "Test";
if(s.equals("Test"))
{
System.out.println("Equal");
}
L'opérateur == est une simple comparaison de valeurs.
Pour les références d'objet, les (valeurs) sont les (références). Donc x == y retourne vrai si x et y font référence au même objet.
@ Melkhiah66 Vous pouvez utiliser la méthode equals au lieu de la méthode '==' pour vérifier l'égalité. Si vous utilisez intern (), il vérifie si l'objet est dans le pool s'il est présent, puis renvoie égal sinon, différent. La méthode equals utilise en interne hashcode et vous permet d'obtenir le résultat souhaité.
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
}
}
</ code>
Si vous comparez une valeur affectée de la chaîne, c'est-à-dire une chaîne primitive, "==" et .equals fonctionneront, mais pour le nouvel objet chaîne, vous ne devez utiliser que .equals, et ici "==" ne fonctionnera pas.
Exemple:
String a = "name";
String b = "name";
if(a == b)
et (a.equals(b))
retournent la valeur true.
Mais
String a = new String("a");
Dans ce cas, if(a == b)
retournera false
Il est donc préférable d'utiliser l'opérateur .equals
...
Généralement, .equals
est utilisé pour la comparaison Object
, où vous souhaitez vérifier si deux Objects
ont une valeur identique.
==
pour la comparaison de référence (les deux Objects
sont les mêmes Object
sur le tas) & pour vérifier si le Object
est nul. Il est également utilisé pour comparer les valeurs des types primitifs.
Je sais que c’est une vieille question, mais voici comment je la vois (je trouve très utile):
Explications techniques
En Java, toutes les variables sont soit types primitifs ou références.
(Si vous avez besoin de savoir ce qu'est une référence: "Les variables d'objet" ne sont que des pointeurs sur des objets. Donc, avec Object something = ...
, quelque chose est vraiment une adresse en mémoire (un nombre).)
==
compare les valeurs exactes. Donc, il compare si les valeurs primitives sont les mêmes, ou si les références (adresses) sont les mêmes. C'est pourquoi ==
ne fonctionne souvent pas sur les chaînes; Les chaînes sont des objets et faire ==
sur deux variables de chaîne ne fait que comparer si l'adresse est la même en mémoire, comme d'autres l'ont souligné. .equals()
appelle la méthode de comparaison des objets, qui comparera les objets réels pointés par les références. Dans le cas des chaînes, il compare chaque caractère pour voir si elles sont égales.
La partie intéressante:
Alors pourquoi ==
retourne-t-il parfois true pour Strings? Notez que les chaînes sont immuables. Dans votre code, si vous le faites
String foo = "hi";
String bar = "hi";
Comme les chaînes sont immuables (lorsque vous appelez .trim()
ou quelque chose, cela produit une nouvelle chaîne, sans modifier l'objet d'origine pointé en mémoire), vous n'avez pas vraiment besoin de deux objets String("hi")
différents. Si le compilateur est intelligent, le bytecode lira pour ne générer qu'un seul objet String("hi")
. Donc si tu le fais
if (foo == bar) ...
juste après, ils pointent sur le même objet et retournent true. Mais vous avez rarement l'intention de le faire. Au lieu de cela, vous demandez à l'utilisateur d'entrer, ce qui crée de nouvelles chaînes de caractères dans différentes parties de la mémoire, etc., etc.
Note: Si vous faites quelque chose comme baz = new String(bar)
le compilateur peut toujours comprendre que c'est la même chose. Mais le point principal est que lorsque le compilateur voit des chaînes littérales, il peut facilement optimiser les mêmes chaînes.
Je ne sais pas comment cela fonctionne au moment de l'exécution, mais je suppose que la JVM ne conserve pas de liste de "chaînes en direct" et vérifie si une même chaîne existe. (Par exemple, si vous lisez une ligne d'entrée deux fois et que l'utilisateur entre la même entrée deux fois, il ne vérifiera pas si la deuxième chaîne d'entrée est identique à la première et les dirigera vers la même mémoire). Cela permettrait d'économiser un peu de mémoire, mais c'est tellement négligeable que les frais généraux n'en valent pas la peine. Encore une fois, il est facile pour le compilateur d’optimiser des chaînes littérales.
Voilà, vous avez une explication sérieuse pour ==
vs. .equals()
et pourquoi cela semble aléatoire.
a==b
Compare les références, pas les valeurs. L'utilisation de ==
avec des références d'objet est généralement limitée aux éléments suivants:
Comparer pour voir si une référence est null
.
Comparer deux valeurs enum. Cela fonctionne car il n'y a qu'un seul objet pour chaque constante enum
.
Vous voulez savoir si deux références se rapportent au même objet
"a".equals("b")
Compare les valeurs pour l'égalité. Comme cette méthode est définie dans la classe Object
, à partir de laquelle toutes les autres classes sont dérivées, elle est automatiquement définie pour chaque classe. Cependant, il n'effectue pas de comparaison intelligente pour la plupart des classes à moins que la classe ne la remplace. Il a été défini de manière significative pour la plupart des Java classes de base. S'il n'est pas défini pour une classe (utilisateur), il se comporte de la même façon que ==
.
La .equals()
vérifie si les deux chaînes ont la même valeur et renvoie la valeur boolean
où l'opérateur ==
vérifie si les deux chaînes sont le même objet.
Quelqu'un a dit sur un post plus haut que == est utilisé pour int et pour vérifier les NULL. Il peut également être utilisé pour vérifier les opérations booléennes et les types de caractères.
Soyez très prudent et vérifiez bien que vous utilisez un caractère et non une chaîne. par exemple
String strType = "a";
char charType = 'a';
pour les chaînes, vous devriez alors cocher la case Cela serait correct
if(strType.equals("a")
do something
mais
if(charType.equals('a')
do something else
serait incorrect, vous devrez faire ce qui suit
if(charType == 'a')
do something else
Utilisez Split plutôt que tokenizer, il fournira sûrement une sortie exacte pour E.g:
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");
}
Après cela, je suis sûr que vous obtiendrez de meilleurs résultats .....