La comparaison caractère, entier et types similaires en Java: Utilisation égale ou ==?

StackOverflow https://stackoverflow.com/questions/735832

  •  09-09-2019
  •  | 
  •  

Question

Je voulais faire quelque chose que Java: Si j'ai un caractère ou un entier ou un long et ces sortes de choses, dois-je utiliser égale ou == suffisante?

Je sais que avec des chaînes, il n'y a aucune garantie qu'il n'y a qu'une seule instance de chaque chaîne unique, mais je ne suis pas sûr d'autres types boxed.

Mon intuition est d'utiliser égaux, mais je veux vous assurer que je ne perds pas la performance.

Était-ce utile?

La solution

EDIT: La spécification fait certains garanties pour les conversions de boxe. De la section 5.1.7 :

  

Si la valeur p étant boxed est vrai,   faux, un octet, un produit de carbonisation dans la plage   \ U0000 à \ u007f, ou un int ou court   entre -128 et 127, puis laissez   r1 et r2 soient les résultats des deux   conversions de boxe de p. C'est toujours   le cas où r1 == r2.

La mise en œuvre peut utiliser un plus grand, l'esprit que vous.

Je vraiment éviter l'écriture de code qui repose sur ce bien. Non pas parce qu'il risque d'échouer, mais parce qu'il est pas évident - peu de gens savent les spécifications bien. (Je pensais que précédemment il dépendait de la mise en œuvre.)

Vous devez utiliser equals ou comparer les valeurs sous-jacentes, i.e..

if (foo.equals(bar))

ou

if (foo.intValue() == bar.intValue())

Notez que même si le autoboxing était garantie d'utiliser des valeurs fixes, d'autres appelants peuvent toujours créer des instances distinctes de toute façon.

Autres conseils

Si vous voulez comparer quoi que ce soit au sujet de la valeur d'un objet, utilisez .equals().

Même (et surtout) si ces objets sont les types primitifs wrapper octet, caractère, Short, Integer, Long, float, double et booléennes.

« == » ne compare jamais l'identité de l'objet et vous qui est très, très rarement ce que vous voulez. Et de fait jamais ce que vous voulez avec les emballages primitifs.

Utilisez uniquement == dans un de ces deux scénarios:

  1. toutes les valeurs participant à la comparaison sont des types primitifs (et de préférence non nombres à virgule flottante)
  2. vous voulez vraiment savoir si deux références se réfèrent au même objet (ce qui inclut la comparaison des enums, parce qu'il ya la valeur est liée à l'identité de l'objet)
//Quick test
public class Test {
  public static void main(String[] args) {
    System.out.println("Are they equal? "+ (new Long(5) == new Long(5)));
  }
}

Sortie:

"Sont-ils égaux? 0"

Réponse:

Non, ils ne sont pas égaux. Vous devez utiliser .equals ou comparer leurs valeurs primitives.

langage Java Spec 5.1.7 :

  

Si la valeur p étant boxed est vrai,   faux, un octet, un produit de carbonisation dans la plage   \ U0000 à \ u007f, ou un int ou court   entre -128 et 127, puis laissez   r1 et r2 soient les résultats des deux   conversions de boxe de p. C'est toujours   le cas où r1 == r2.

et

  

Discussion

     

Idéalement, la boxe une primitive donnée   valeur p, serait toujours donner un   référence identique. En pratique, cela,   peut ne pas être réalisable à l'aide existante   techniques de mise en œuvre. Les règles   ci-dessus sont un compromis pragmatique. le   clause finale exige que ci-dessus   certaines valeurs communes sont toujours mis en boîte   en objets impossibles à distinguer. le   la mise en œuvre peut mettre en cache ces derniers, paresseusement   ou avec impatience.

     

Pour d'autres valeurs, cette formulation   toutes les hypothèses sur ne permettant pas la   identité des valeurs sur la boxed   part du programmeur. Cela permettrait   (Mais pas besoin) le partage d'une partie ou   toutes ces références.

     

Cela garantit que, dans le plus courant   des cas, le comportement sera le   une souhaitée, sans imposer une excessive   pénalité de performance, en particulier sur   petits appareils. Moins de mémoire limitée   mises en œuvre pourraient, par exemple,   cache tous les caractères et courts métrages, comme   ainsi que des entiers et désire ardemment dans la   gamme de -32K -. + 32K

Ainsi, dans certains cas, == travaillera, dans beaucoup d'autres, il ne sera pas. Utilisez toujours .equals pour être sûr puisque vous ne pouvez pas le concessionnaire d'(généralement) la façon dont les cas ont été obtenus.

Si la vitesse est un facteur (la plupart .equals commencent par une comparaison ==, ou du moins ils le devraient) et vous pouvez gurantee comment ils ont été alloués et ils se situent dans les plages ci-dessus alors == est sûr.

Certaines machines virtuelles peut augmenter cette taille, mais il est plus sûr d'assumer la plus petite taille tel que spécifié par la spécification langauge que de compter sur un comportement VM particulier, à moins que vous vraiment vraiment vraiment besoin.

Implémentations des égaux méthode (Object o) commencent presque toujours avec

if(this == o) return true;

en utilisant equals même si == est vrai est vraiment pas beaucoup d'un coup de performance.

Je recommande toujours * en utilisant la méthode equals sur les objets.

* Bien sûr, il y a très peu de moments où vous ne devriez pas prendre ce conseil.

La réponse générale est pas , vous n'êtes pas garanti que, pour la même valeur numérique, les objets longs que vous obtenez sont les mêmes (même si vous vous limiter à l'aide Long.valueOf ()).

Cependant, il est possible que vous obtiendrez une amélioration de la performance en essayant d'abord de tester l'égalité des références (en utilisant ==), puis, en cas d'échec, essayant equals (). Tout dépend des coûts comparatifs du test == supplémentaire et l'appel de méthode ... Votre kilométrage peut varier, mais il vaut la peine d'essayer un simple test en boucle pour voir ce qui est mieux.

Il convient de noter que les valeurs auto-boxed seront mis en commun les utilisations objet si elles sont disponibles. Ceci est la raison pour laquelle (entier) 0 == (entier) 0 mais (entier) 128! = (Entier) 128 pour Java 6u13

J'aime voir visuellement le résultat:

  public static void main(String[] args)
  {
        Integer a = 126; //no boxed up conversion, new object ref
        Integer b = 126; //no boxed up conversion, re-use memory address
        System.out.println("Are they equal? " + (a == b)); // true
        Integer a1 = 140; //boxed up conversion, new object
        Integer b1 = 140; //boxed up conversion, new object
        System.out.println("Are they equal? " + (a1 == b1)); // false
        System.out.println("Are they equal? " + (new Long(5) == new Long(5))); // false
  }

== compare la référence de l'objet alors que equals(Object obj) compare l'égalité des objets. S'il n'y a jamais plus d'une instance d'un égal objet existant vous doit utilisation equals pour la comparaison de l'égalité.

Exemples:

Integer i1 = new Integer(12345);
Integer i2 = new Integer(12345);

ce sont les différentes instances d'objet, mais sont égaux selon l'égalité de nombre entier, vous devez donc utiliser equals(Object obj)

public enum Gender {
    MALE, FEMALE;
}

dans ce cas, il n'y aura qu'un seul exemple de FEMALE existe donc == est sûr à utiliser.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top