2011-10-11 16 views
27

Va bene, diciamo che un intero A dovrebbe avere la gamma di: [0 ... 2147483647]Intervalli in Java, qual è l'approccio migliore?

Quindi, in pratica, il codice pseudo va in questo modo: se intero A è all'interno di tale intervallo fare qualcosa ... altro fare qualcos'altro.

So che può essere eseguito da una semplice istruzione if..else, ma esiste un modo più efficiente per verificare se A è compreso nell'intervallo?

Non voglio andare con questo perché sembra così sbagliato:

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

edit: Penso che sto facendo la domanda sbagliata, quindi sono solo andando chiedere, come farlo utilizzando l'approccio polimorfico. Ho solo bisogno di qualche semplice illustrazione perché il libro che ho letto ha un esempio molto lungo. > _ < Siamo spiacenti.

risposta

1

Avrai un controllo se non importa quanto tu cerchi di ottimizzare questo calcolo non troppo intenso :) Puoi sottrarre il limite superiore dal numero e se è positivo, sai che sei fuori portata. Puoi forse eseguire qualche logica booleana di spostamento dei bit per capirlo e puoi anche usare il teorema di Fermat se vuoi (scherzando :) Ma il punto è "perché" hai bisogno di ottimizzare questo confronto? Qual è lo scopo?

+1

Sono con l'OP - questo tipo di controllo procedurale si è sempre sentito imbarazzante. Preferisco i contratti dichiarativi quando sono disponibili, anche se il primo alla fine si riduce a quest'ultimo. –

+0

Ho bisogno di ottimizzare perché lo trovo molto più lento quando diciamo che A è un numero davvero grande. E se scelgo di espandermi e fare altri controlli all'interno di quella dichiarazione if..else? > _ < –

+2

Stai scherzando - lento? Come in te l'hai misurato per esibirti male? – StaxMan

14

Si potrebbe creare una classe per rappresentare questo

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

Ora vedo che stavi cercando di evitare il se. Pensavo che non ti piacesse la sintassi del confronto nel se ... oh, va bene. – ScArcher2

+0

Con questa implementazione, non è possibile rappresentare un intervallo vuoto (assumendo 'low <= high'). O l'intervallo deve essere semiaperto '[basso, alto]' altrimenti usare un 'extent' invece di' high'. – Richard

5

Se si sta verificando contro un sacco di intervalli, io suggerisco di usare un interval tree.

+0

Esiste una libreria Java nota che implementa un albero ad intervalli? – dokaspar

30

Apache Commons Lang ha uno Range class per eseguire intervalli arbitrari.

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

Guava Range ha API simile.

Se si desidera verificare se un numero si adatta a un valore lungo o un valore int, è possibile provare a utilizzarlo tramite BigDecimal. Esistono metodi per longValueExact e intValueExact che generano eccezioni se il valore è troppo grande per tali precisioni.

+2

Sì, ma come pensi che '.taintains (...)' sia implementato? ;) (Con un if/else di sicuro :) – PhD

3

Potreste usare java.time.temporal.ValueRange che accetta long e potrebbe funzionare anche con 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

Non ho mai saputo di questa gemma incorporata fino ad ora. Grazie per la condivisione! – TinkerTenorSoftwareGuy

+0

@TinkerTenorSoftwareGià che tu sia il benvenuto (0: – c0der

2

So che questo è piuttosto una vecchia questione, ma con Java 8 di Streams è possibile ottenere una serie di int s come questo:

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

allora si può fare qualcosa di simile:

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