Question

J'ai une longue série de comparaisons à faire en Java, et je voudrais savoir si un ou plusieurs d'entre eux viennent comme vrai. La chaîne de comparaisons a été longue et difficile à lire, donc je l'ai cassé pour la lisibilité, et est allé à utiliser automatiquement un opérateur de raccourci |= plutôt que negativeValue = negativeValue || boolean.

boolean negativeValue = false;
negativeValue |= (defaultStock < 0);
negativeValue |= (defaultWholesale < 0);
negativeValue |= (defaultRetail < 0);
negativeValue |= (defaultDelivery < 0);

Je me attends negativeValue est vrai si l'un de la valeur par défaut valeurs sont négatives. Est-ce valable? Est-il faire ce que je pense? Je ne pouvais pas le voir mentionné sur le site de Sun ou stackoverflow, mais Eclipse ne semble pas avoir un problème avec elle et le code est compilé et exécuté.


De même, si je voulais effectuer plusieurs intersections logiques, pourrais-je utiliser &= au lieu de &&?

Était-ce utile?

La solution

Le |= est un opérateur d'affectation de composé ( JLS 15.26.2 ) pour l'opérateur logique booléen | ( JLS 15.22.2); à ne pas confondre avec le conditionnel ou || ( Pourquoi ne pas Java ont des versions d'affectation des composés conditionnelles et conditionnelles et ou opérateurs? (&& =, || =) .

Autres conseils

Il est pas un opérateur « raccourci » (ou court-circuit) de la manière que || et && sont (en ce sens qu'ils ne seront pas évaluer l'ERS si elles connaissent déjà le résultat sur la base du LHS), mais il fera ce que vous voulez en termes de de travail .

A titre d'exemple de la différence, ce code sera bien si text est nulle:

boolean nullOrEmpty = text == null || text.equals("")

alors que ce ne sera pas:

boolean nullOrEmpty = false;
nullOrEmpty |= text == null;
nullOrEmpty |= text.equals(""); // Throws exception if text is null

(Il est évident que vous pourriez faire pour "".equals(text) ce cas particulier -. Je vais juste essayer de démontrer le principe)

Vous pourriez avoir une déclaration. Exprimé sur plusieurs lignes, il lit presque exactement comme votre code d'échantillon, seulement moins impératif:

boolean negativeValue
    = defaultStock < 0 
    | defaultWholesale < 0
    | defaultRetail < 0
    | defaultDelivery < 0;

Pour les expressions les plus simples, en utilisant | peut être plus rapide que || parce que même si elle évite de faire une comparaison, cela signifie implicitement en utilisant une branche et qui peut être beaucoup plus cher.

Bien qu'il pourrait être trop pour votre problème, Goyave bibliothèque a une syntaxe agréable avec Predicates et fait l'évaluation de court-circuit ou / et Predicates.

Pour l'essentiel, les comparaisons sont transformées en objets, emballé dans une collection, puis réitérés plus. Pour ou prédicats, les premiers vrais retours de succès de l'itération, et vice-versa pour et.

S'il est sur la lisibilité, j'ai le concept de séparation testé les données de la logique de test. Exemple de code:

// declare data
DataType [] dataToTest = new DataType[] {
    defaultStock,
    defaultWholesale,
    defaultRetail,
    defaultDelivery
}

// define logic
boolean checkIfAnyNegative(DataType [] data) {
    boolean negativeValue = false;
    int i = 0;
    while (!negativeValue && i < data.length) {
        negativeValue = data[i++] < 0;
    }
    return negativeValue;
}

Le code ressemble plus bavard et explicite. Vous pouvez même créer un tableau en appel de méthode, comme ceci:

checkIfAnyNegative(new DataType[] {
    defaultStock,
    defaultWholesale,
    defaultRetail,
    defaultDelivery
});

Il est plus lisible que « chaîne de comparaison », et a également l'avantage de la performance de court-circuit (au coût de l'allocation de tableau et appel de méthode).

Edit: peut être simplement atteint encore plus de lisibilité en utilisant les paramètres varargs:

Signature de la méthode serait:

boolean checkIfAnyNegative(DataType ... data)

Et l'appel pourrait ressembler à ceci:

checkIfAnyNegative( defaultStock, defaultWholesale, defaultRetail, defaultDelivery );

Il est un ancien poste mais dans le but de fournir une perspective différente pour les débutants, je voudrais donner un exemple.

Je pense que le cas d'utilisation la plus courante pour un opérateur composé similaire serait +=. Je suis sûr que nous avons écrit tous quelque chose comme ceci:

int a = 10;   // a = 10
a += 5;   // a = 15

Quel a été le point de cela? Le point était d'éviter boilerplate et éliminer le code répétitif.

Ainsi, la ligne suivante fait exactement la même chose, en évitant de taper la b1 variables deux fois dans la même ligne.

b1 |= b2;
List<Integer> params = Arrays.asList (defaultStock, defaultWholesale, 
                                       defaultRetail, defaultDelivery);
int minParam = Collections.min (params);
negativeValue = minParam < 0;

|| booléen OR logique
| OU binaire

| = OU inclusif et au niveau du bit opérateur d'affectation

La raison pour laquelle | = ne shortcircit pas est parce qu'il ne Bitwise ou non un OU logique. C'est-à-dire:

C |= 2 is same as C = C | 2

Tutoriel pour les opérateurs java

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