2011-10-11 4 views
27

D'accord, disons un entier A doit avoir l'ordre de: [0 ... 2147483647]Plages en Java, quelle est la meilleure approche?

Donc, fondamentalement, le pseudo-code va comme ceci: si entier A est dans cette plage faire quelque chose ... sinon faire autre chose.

Je sais que cela peut être accompli par une simple instruction if..else, mais y a-t-il un moyen plus efficace de vérifier si A est dans la plage?

Je ne veux pas aller avec cela parce qu'il semble si mal:

if (A >= 0 && A <= 2147483647){ 
    // do something 
}else{ 
    // do something else 
} 

edit: Je pense que je pose la mauvaise question, je suis juste me demander, comment faire en utilisant l'approche polymorphe. J'ai juste besoin d'une illustration simple parce que le livre que j'ai lu a un très long exemple. > _ < Désolé.

Répondre

1

Vous aurez un if-check, quel que soit l'efficacité avec laquelle vous essayez d'optimiser ce calcul pas si intensif :) Vous pouvez soustraire la borne supérieure du nombre et si elle est positive, vous savez que vous êtes hors de portée. Vous pouvez peut-être effectuer une logique de décalage booléen pour le comprendre et vous pouvez même utiliser le théorème de Fermat si vous voulez (blague :) Mais le point est "pourquoi" avez-vous besoin d'optimiser cette comparaison? Quel est le but?

+1

Je suis avec le PO - ce genre de vérification procédurale a toujours été gênant. Je préfère les contrats déclaratifs lorsqu'ils sont disponibles, même si le premier se réduit éventuellement au second. –

+0

J'ai besoin d'optimiser parce que je le trouve beaucoup plus lent quand disons que A est un très grand nombre. Et si je choisis de développer et de faire d'autres vérifications dans cette déclaration if..else? > _ < –

+2

Vous devez rigoler - lent? Comme vous l'avez mesuré pour performer mal? – StaxMan

14

Vous pouvez créer une classe pour représenter ce

Range range = new Range(0, 2147483647); 

if(range.contains(A)){ 
    //do something 
}else{ //do something else } 



public class Range { 

    private int low; 
    private int high; 

    public Range(int low, int high){ 
     this.low = low; 
     this.high = high; 
    } 

    public boolean contains(int number){ 
     return (number >= low && number <= high); 
    } 
} 
+0

Je vois maintenant que vous essayiez d'éviter le si. Je pensais que tu n'aimais pas la syntaxe de comparaison dans le si ... eh bien. – ScArcher2

+0

Avec cette implémentation, vous ne pouvez pas représenter une plage vide (en supposant 'low <= high'). Soit l'intervalle doit être semi-ouvert '[low, high)' ou alors utiliser 'extent' au lieu de' high'. – Richard

5

Si vous vérifiez contre beaucoup d'intervalles, je suggère d'utiliser un interval tree.

+0

Y a-t-il une bibliothèque Java connue qui implémente un arbre d'intervalle? – dokaspar

30

Apache Commons Lang a un Range class pour effectuer des plages arbitraires.

Range<Integer> test = Range.between(1, 3); 
System.out.println(test.contains(2)); 
System.out.println(test.contains(4)); 

Guava Range a API similaire.

Si vous souhaitez simplement vérifier si un nombre correspond à une valeur longue ou à une valeur int, vous pouvez essayer de l'utiliser via BigDecimal. Il existe des méthodes pour longValueExact et intValueExact qui lancent des exceptions si la valeur est trop grande pour ces précisions.

+2

Oui, mais comment pensez-vous que '.contains (...)' est implémenté? ;) (Avec un if/else à coup sûr :) – PhD

3

Vous pouvez utiliser java.time.temporal.ValueRange qui accepte long et travailleraient aussi avec int:

int a = 2147; 

    //Use java 8 java.time.temporal.ValueRange. The range defined 
    //is inclusive of both min and max 
    ValueRange range = ValueRange.of(0,2147483647); 

    if(range.isValidValue(a)) { 
     System.out.println(" in range "); 
    }else { 
     System.out.println(" not in range "); 
    } 
+0

Je n'ai jamais connu cette gemme intégrée jusqu'à présent. Merci d'avoir partagé! – TinkerTenorSoftwareGuy

+0

@TinkerTenorSoftwareGuy vous êtes le bienvenu (0: – c0der

2

Je sais que cela est tout à fait une question ancienne, mais avec Java 8 de cours d'eau, vous pouvez obtenir une gamme de int s comme celui-ci:

IntStream.rangeClosed(0, Integer.MAX_VALUE); // gives an IntStream of integers from 0 through Integer.MAX_VALUE 

vous pouvez faire quelque chose comme ceci:

if (IntStream.rangeClosed(0, Integer.MAX_VALUE).matchAny(n -> n == A)) { 
    // do something 
} else { 
    // do something else 
} 
Questions connexes