English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Les problèmes de comparaison en Java sont des questions très fondamentales et faciles à confondre. Aujourd'hui, nous faisons une comparaison détaillée et une organisation des points qui sont faciles à faire des erreurs, dans l'espoir que cela puisse aider les apprenants et les entretiens d'embauche.
Premièrement, la différence entre == et equals()
Tout d'abord, nous devons savoir la différence entre == et equals(), == compare toujours la valeur d'adresse, pour les types de données de base, la comparaison == est en fait la comparaison de la valeur de la variable, pour les types de données de référence, la comparaison est la valeur d'adresse. Il est particulièrement需要注意的是 le type String, il est facile de l'utiliser à tort ==, ce qui peut facilement entraîner des erreurs. La méthode equals() est une méthode de la classe Object, nous savons que dans Java, toutes les classes héritent par défaut de la classe Object, donc tous les objets de classe auront la méthode equals(). La méthode equals() de la classe Object est montrée dans l'image suivante :
Il peut être vu dans le code source que la méthode equals() de la classe Object utilise également == en coulisse, donc ce qu'elle compare en réalité est également la valeur d'adresse. Par conséquent, si nous voulons utiliser la méthode equals() pour d'autres comparaisons, nous devons redéfinir la méthode equals().
Deuxièmement, les types de données de base et leurs classes enveloppes
Nous savons tous que byte, short, int, long, boolean, char, double, float ces huit sont des types de données de base, les variables déclarées par eux sont stockées dans la mémoire de pile. Quant aux types de données encapsulés correspondants (Byte, Short, Integer, Long, Boolean, Character, Double), les variables définies par eux existent dans la mémoire d'heap. Pour les types de données de base, leur comparaison est relativement simple, c'est-à-dire que la comparaison de l'égalité utilise ==, et la comparaison de la taille utilise <, >, <=, >=. Quant aux types de données encapsulés, cela est différent.
Tout d'abord, pour juger de l'égalité, voyons le résultat d'exécution du code suivant :
package dailytest; import org.junit.Test; /** * Résumé des comparaisons en Java * @author yrr */ public class JavaCompareTest { /** * La comparaison de l'égalité du type Integer */ @Test public void test01() { int n3 = 48; System.out.println("--------Lors de l'utilisation d'objets new, lorsque la valeur est dans [-127,128entre---------"); Integer n7 = new Integer(48); Integer n8 = new Integer(48); System.out.println(n7 == n8); //false System.out.println(n7 == n3); //true System.out.println("--------La méthode d'affectation directe, lorsque la valeur est dans [-128,127entre---------"); Integer n1 = 48; Integer n2 = 48; System.out.println(n3 == n1); //true System.out.println(n1 == n2); //true System.out.println(n1.equals(n2)); //true System.out.println(n1.equals(n3)); //true System.out.println(n1.intValue() == n2.intValue()); //true System.out.println("--------La méthode d'affectation directe, lorsque la valeur n'est pas dans [-127,128entre---------"); Integer n4 = 128; Integer n5 = 128; int n6 = 128; System.out.println(n4 == n5); //false System.out.println(n4 == n6); //true System.out.println(n4.equals(n5)); //true System.out.println(n4.equals(n6)); //true System.out.println(n4.intValue() == n5.intValue()); //true //Lors de l'utilisation de la méthode Integer.intValue(), il faut vérifier si elle est nulle pour éviter les NullPointException } /** * La comparaison de l'égalité du type Long */ @Test public void test02() { //Il faut noter ici que lors de la définition avec long, il n'est pas nécessaire d'ajouter L ou l, mais lors de l'utilisation de Long, il est obligatoire, sinon il y aura une erreur //Les constructions doivent être ajoutées pour montrer la distinction long n3 = 48L; System.out.println("--------Lors de l'utilisation d'objets new, lorsque la valeur est dans [-127,128entre---------"); Long n7 = new Long(48); Long n8 = new Long(48); System.out.println(n7 == n8); //false System.out.println(n7 == n3); //true System.out.println("--------La méthode d'affectation directe, lorsque la valeur est dans [-127,128entre---------"); Long n1 = 48L; Long n2 = 48L; System.out.println(n3 == n1); //true System.out.println(n1 == n2); //true System.out.println(n1.equals(n2)); //true System.out.println(n1.equals(n3)); //true System.out.println(n1.intValue() == n2.intValue()); //true System.out.println("--------La méthode d'affectation directe, lorsque la valeur n'est pas dans [-127,128entre---------"); Long n4 = 128L; Long n5 = 128L; long n6 = 128; System.out.println(n4 == n5); //false System.out.println(n4 == n6); //true System.out.println(n4.equals(n5)); //true System.out.println(n4.equals(n6)); //true System.out.println(n4.intValue() == n5.intValue()); //true //Lors de l'utilisation de la méthode Long.intValue(), il faut vérifier si elle est nulle pour éviter les NullPointException } }
Pour les résultats d'exécution ci-dessus, voici les explications suivantes :
Tout d'abord, pour déclarer un objet Integer ou Long avec la méthode new, car les objets new sont tous alloués dans la pile, donc même si les deux valeurs sont les mêmes, pour ==, il s'agit de comparer les valeurs d'adresse, donc il renvoie faux. Pour les classes de wrappers de types de données de base, la méthode equals() est redéfinie pour comparer la taille des valeurs, donc l'utilisation de la méthode equals() peut être jugée selon la taille des valeurs. Pour le problème de comparaison entre une variable Integer et une variable int, on constate que la comparaison est basée sur la taille des valeurs, car lors de la comparaison, le type Integer effectue un dépaquetage automatique et se transforme en type int. Les explications des trois points précédents s'appliquent à tous les types de paquets Pour la méthode d'affectation directe, la valeur48deux variables Integer, l'opérateur == renvoie true, tandis que lorsque la valeur128après cela, est faux. Cela est dû au fait que, au niveau inférieur, pour les deux variables Integer n1 = 48;Cette méthode d'affectation directe appelle en réalité la méthode Integer.value(). Nous pouvons jeter un coup d'œil rapide au code source de la méthode Integer.value() comme montré dans l'image suivante :
Nous pouvons voir qu'il y a une condition if ici, lorsque l'entrée i est dans [-128,127],est retourné directement à partir de l'array IntegerCache. Donc, pour les valeurs dans cette plage, elles sont toutes retournées par l'adresse de l'array correspondant, donc l'utilisation de == retourne true. Ce qui n'est pas dans cette plage, est un objet newé, donc il retourne false. Ce résultat est valable pour Byte, Short, Integer, Long types (les intéressés peuvent consulter le code source de leurs méthodes value() correspondantes), car la plage du type Byte est [}}-128,127],donc pour le type Byte, l'utilisation de == et equals() n'a pas de différence.
Pour la comparaison de grandeurs, l'utilisation de >, <, <=, >= ne pose pas de problème, elles procèdent à l'auto-dépaquetage. Cependant, nous recommandons généralement les deux méthodes suivantes pour la comparaison de grandeurs :
Utilisez la méthode xxxValue() pour convertir en type de données de base et comparer. Utilisez la méthode compareTo() pour comparer. Dans les classes de wrappers, la méthode compareTo() est redéfinie. En consultant le code source de compareTo(), on peut voir qu'elle utilise également la dépaquetage automatique pour convertir en type de données de base et comparer.
Deuxième partie : Comparaison des objets Java
Après les explications ci-dessus, la comparaison des objets est plus facile. Le principe est le même.
1. Comparaison du type String
Il convient de noter que le type String ne peut pas utiliser directement >, <=, >=, <, cela会产生编译异常。
package dailytest; import org.junit.Test; /** * Résumé des comparaisons en Java * @author yrr */ public class JavaCompareTest { @Test public void test03() { String s1 = new String("123"); String s2 = new String("123"); System.out.println(s1 == s2); //false System.out.println(s1.equals(s2)); String s3 = "234"; String s4 = "234"; System.out.println(s3 == s4); //true System.out.println(s3.equals(s4)); //true //System.out.println(s1 <= s3); //L'opérateur < n'est pas défini pour le type d'argument(s) java.lang.String, java.lang.String System.out.println(s1.compareTo(s3) < 0); //true } }
2. Comparaison des objets de classe
Les conclusions de comparaison des objets de classe sont les mêmes, mais elles sont un peu plus complexes par rapport aux types de données de base et String.
Selon une règle donnée, pour déterminer si deux objets sont égaux, il faut redéfinir la méthode equals() dans la classe à tester, voici un exemple de code :
package dailytest; import org.junit.Test; /** * Résumé des comparaisons en Java * @author yrr */ public class JavaCompareTest { @Test public void test04() { Person p1 = new Person("yrr",18); Person p2 = new Person("yrr",18); System.out.println(p1 == p2); //false System.out.println(p2.equals(p1)); //true } } class Person{ private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public Integer getAge() { return age; } @Override public boolean equals(Object obj) { Person person = (Person) obj; return name.equals(person.getName()) && age.equals(person.getAge()); } }
Et si l'on veut comparer la taille de deux objets (c'est aussi une question fréquente lors des entretiens d'embauche), il y a deux méthodes :
La classe comparée implémente l'interface Comparable et redéfinit la méthode compareTo() Soit une classe qui redéfinit l'interface Comparator ou utilise une classe interne, redéfinit la méthode compare() Les différences entre les deux : la première est définie sur la classe comparée, tandis que la seconde est définie à l'extérieur de la classe comparée. Grâce à cette distinction, les avantages et les inconvénients des deux méthodes sont évidents : la première est simple, mais nécessite des modifications de la classe comparée, tandis que la seconde n'exige pas de modifications du code original et est plus flexible.
Première méthode, voici un exemple de code :
package dailytest; import org.junit.Test; /** * Résumé des comparaisons en Java * @author yrr */ public class JavaCompareTest { @Test public void test5() { Person p1 = new Person("yrr",18); Person p2 = new Person("wx",19); System.out.println(p1.compareTo(p2) < 0); } } class Person implements Comparable<Person>{ private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public Integer getAge() { return age; } @Override public int compareTo(Person o) { return this.getAge(); - o.getAge(); } }
Deuxième méthode, voici un exemple de code :
package comparator; import java.util.Arrays; import java.util.Comparator; public class MyComparator { public static void main(String[] args) { User[] users = new User[] { new User("u")}1001", 25),}} new User("u1002", 20), new User("u1003", 21) }; Arrays.sort(users, new Comparator<User>() { @Override public int compare(User o1, User o2) { return o1.getAge() - o2.getAge(); } }); for (int i = 0; i < users.length; i++) { User user = users[i]; System.out.println(user.getId() + " " + user.getAge()); } } } class User { private String id; private int age; public User(String id, int age) { this.id = id; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getId() { return id; } public void setId(String id) { this.id = id; } }
Voici les points relatifs à la comparaison en Java que nous avons présentés cette fois. Si vous avez d'autres questions, vous pouvez les discuter dans la zone de commentaires ci-dessous. Merci de votre soutien.
Déclaration : Le contenu de cet article est tiré du réseau, propriété des auteurs respectifs, apporté par les utilisateurs d'Internet de manière spontanée et téléversé. Ce site ne détient pas de droits de propriété, n'a pas été édité par l'homme, et n'assume aucune responsabilité juridique. Si vous trouvez du contenu suspect de violation de droits d'auteur, veuillez envoyer un e-mail à : notice#oldtoolbag.com (veuillez remplacer # par @ lors de l'envoi d'un e-mail pour signaler une violation, et fournir des preuves pertinentes. Une fois vérifié, ce site supprimera immédiatement le contenu suspect de violation de droits d'auteur.)