2011-09-30 14 views
36

Una domanda semplice ma Google non ha aiutato molto.Il modo migliore per formattare più "o" condizioni in un'istruzione if (Java)

ho un if con molte condizioni (deve controllare da 10 o 15 le costanti per vedere se qualcuno di loro sono presenti.)

Invece di scrivere qualcosa di simile:

if (x == 12 || x == 16 || x == 19 || ...) 

c'è un modo per formattarlo come

if x is [12, 16, 19]? 

Basta chiedersi se c'è un modo più semplice per codificare questo, qualsiasi aiuto apprezzato.

Modifica: le risposte sono state molto utili, ma mi è stato chiesto di aggiungere più dettagli da alcune persone, quindi lo farò per saziare la loro curiosità. Stavo facendo una lezione di validazione della data che doveva garantire che i giorni non fossero> 30 nei mesi che hanno solo 30 giorni (di cui ce ne sono 4, credo) e stavo scrivendo un'istruzione if per verificare cose come questa:

if (day > 30 && (month == 4 || month == 6 || month == 9 || month == 11)) 

Mi stavo chiedendo se ci fosse un modo più veloce per codificare cose del genere - molte delle risposte qui sotto hanno aiutato :).

+0

Puoi dare un esempio migliore di ciò che stai cercando di fare? Forse una soluzione sta nel pensarci? –

risposta

37

Uso spesso questo tipo di schema. E 'molto compatto:

// Define a constant in your class. Use a HashSet for performance 
private static final Set<Integer> values = new HashSet<Integer>(Arrays.asList(12, 16, 19)); 

// In your method: 
if (values.contains(x)) { 
    ... 
} 

Un HashSet è usato qui per dare la buona prestazione di look-up - anche molto grandi insiemi di hash sono in grado di eseguire in modo estremamente rapido.

Se le prestazioni non è importante, è possibile codificare l'essenza di esso in una riga:

if (Arrays.asList(12, 16, 19).contains(x)) 

ma sai che creerà una nuova ArrayList ogni volta che esegue.

+2

if (Arrays.asList (12, 16, 19) .contains (x)) –

+0

Brian, ho aggiunto il tuo suggerimento con un avvertimento sulle prestazioni – Bohemian

+1

Preferisco usare un set di "lista" per questo, ma questo non avrà alcun effetto su quei pochi elementi. –

3

Si potrebbe cercare la presenza di una chiave di mappa o vedere se è in un set.

A seconda di cosa si sta effettivamente facendo , però, è che si stia tentando di risolvere il problema sbagliato :)

3

Usare una collezione di qualche tipo - questo renderà il codice più leggibile e nascondere tutto quelle costanti. Un modo semplice sarebbe con una lista:

// Declared with constants 
private static List<Integer> myConstants = new ArrayList<Integer>(){{ 
    add(12); 
    add(16); 
    add(19); 
}}; 

// Wherever you are checking for presence of the constant 
if(myConstants.contains(x)){ 
    // ETC 
} 

come punti di Boemia fuori l'elenco delle costanti possono essere statici in modo che sia accessibile in più di un luogo.

Per chiunque sia interessato, l'elenco nel mio esempio utilizza double brace initialization. Da quando mi sono imbattuto recentemente, ho trovato utile scrivere rapidamente le inizializzazioni delle liste sporche &.

+1

o 'if (Arrays.asList (new int [] {12,16,19}). Contiene (x)) {...}' –

+0

@Bala sure! In ogni caso una lista è solo un esempio di una collezione da usare qui. Come una delle altre risposte suggerite, un set potrebbe essere migliore per garantire che le costanti siano uniche ... O una tabella hash per velocizzare la ricerca, ecc. –

10

Vuoi passare a questo ??

switch(x) { 
    case 12: 
    case 16: 
    case 19: 
     //Do something 
     break; 
    default: 
     //Do nothing or something else.. 
     break; 
} 
3

Se l'insieme delle possibilità è "compatto" (vale a dire più grande valore - minore valore è, diciamo, meno di 200) si potrebbe considerare una tabella di ricerca. Questo sarebbe particolarmente utile se si ha una struttura come

if (x == 12 || x == 16 || x == 19 || ...) 
else if (x==34 || x == 55 || ...) 
else if (...) 

Impostare un array con valori identificare il ramo da adottare (1, 2, 3 nell'esempio di cui sopra) e poi i test diventano

switch(dispatchTable[x]) 
{ 
    case 1: 
     ... 
     break; 
    case 2: 
     ... 
     break; 
    case 3: 
     ... 
     break; 
} 

Se questo è appropriato dipende dalla semantica del problema.

Se un array non è appropriato, è possibile utilizzare un Map<Integer,Integer>, o se si desidera solo per verificare l'appartenenza a una singola istruzione, un Set<Integer> farebbe.C'è un sacco di potenza di fuoco per una semplice dichiarazione if, quindi, senza più contesto, è un po 'difficile guidarti nella giusta direzione.

4

No, non è possibile farlo in Java. tuttavia è possibile scrivere un metodo come segue:

boolean isContains(int i, int ... numbers) { 
    // code to check if i is one of the numbers 
    for (int n : numbers) { 
     if (i == n) return true; 
    } 
    return false; 
} 
2

con Java 8, è possibile utilizzare un flusso primitiva:

if (IntStream.of(12, 16, 19).anyMatch(i -> i == x)) 

ma ciò potrebbe avere un leggero sovraccarico (o non), a seconda del numero di confronti.

Problemi correlati