2012-01-22 12 views
15

In sostanza, quello che voglio fare è controllare due interi contro un dato valore, dunque, classicamente quello che si potrebbe fare è qualcosa di simile:Esiste un modo più semplice per verificare più valori rispetto a un valore in un'istruzione if?

//just to get some values to check 
int a, b; 
a = (int)(Math.random()*5); 
b = (int)(Math.random()*5); 

//the actual thing in question 
if(a == 0 || b == 0) 
{ 
//Then do something 
} 

Ma esiste un formato più conciso per fare questo? Forse simile a questo (che restituisce un tipo di operando cattivo):

//just to get some values to check 
int a, b; 
a = (int)(Math.random()*5); 
b = (int)(Math.random()*5); 

//the actual thing in question 
if((a||b) == 0) 
{ 
//Then do something 
} 
+2

Perché lo vuoi anche tu? – harold

+2

possibile duplicato di [Il modo migliore per formattare più 'o' condizioni in un'istruzione if (Java)] (http://stackoverflow.com/questions/7604814/best-way-to-format-multiple-or-conditions-in -an-if-statement-java) –

+0

perché il codice apparirebbe meglio allora? –

risposta

21

Sfortunatamente non esiste un tale costrutto in Java.

E 'questo tipo di confronto è frequente nel codice, è possibile implementare una piccola funzione che eseguirà la verifica per voi:

public boolean oneOfEquals(int a, int b, int expected) { 
    return (a == expected) || (b == expected); 
} 

allora si potrebbe utilizzare in questo modo:

if(oneOfEquals(a, b, 0)) { 
    // ... 
} 

Se non si desidera limitare yourselft a numeri interi, è possibile effettuare la funzione di cui sopra generica:

public <T> boolean oneOfEquals(T a, T b, T expected) { 
    return a.equals(expected) || b.equals(expected); 
} 

Nota che in questo caso il runtime Java eseguirà il boxing automatico e l'unboxing per i tipi primitivi (come int), che è una perdita di prestazioni.

+0

Sì, ma cosa succede se ho tre variabili, o quattro, o una quantità maggiore che per qualche motivo non sono in un array? Dovrei riscrivere questa funzione ogni volta per adattarsi al diverso numero di input. – Amndeep7

+2

Non esattamente, è possibile utilizzare l'elenco di parametri di lunghezza variabile: 'public booleano oneOfEquals (T expected, T ... actual) {...}' e un ciclo for nel corpo della funzione. Ti mostrerò un esempio se desideri @ Amndeep7. – buc

+0

Sembra abbastanza semplice da comprendere, una domanda però, che cosa diventa ... reale? È una lista di qualche tipo o un array o cosa? – Amndeep7

4

penso che un bit per bit OR:

if ((a | b) == 0) . . . 

potrebbe funzionare se si desidera controllare specificamente per 0. I' Non sono sicuro se questo consente di risparmiare tempo di esecuzione. Più precisamente, rende il codice criptico, che renderà maledetto il futuro manutentore di questo codice (anche se stesso). Consiglio di attenersi all'opzione più tipografica.

Bah. Ho interpretato male la logica originale di OP.

un altro andare ...

Se si vuole verificare se una qualsiasi delle molte variabili è pari ad un valore atteso, una funzione generica potrebbe funzionare:

public <T> boolean exists(T target, T... values) { 
    for (T value : values) { 
     if (target == null) { 
      if (value == null) { 
       return true; 
      } 
     } else if (target.equals(value)) { 
      return true; 
     } 
    } 
    return false; 
} 

Questo lavoro per qualsiasi numero di oggetti di un tipo I primitivi saranno chiusi automaticamente in modo che funzionino anche con loro. Il tuo codice originale sarà qualcosa di simile:

if (test(0, a, b)) { 
    // do something 
} 

(A nome del metodo migliore sarebbe un disperato bisogno di prendere in considerazione anche se questo un miglioramento rispetto a quello che hai ora Anche se il test si espande fino a 3 o 4 variabili, mi chiedo. . la necessità di questo tipo di cosa) si noti che questo funziona anche con le matrici:

int[] values = { . . . }; 
if (test(0, values)) { . . . 

e può essere utilizzato per verificare se una matrice (o qualsiasi di una collezione di variabili) è null.

+0

Ma c'è un modo per generalizzare questo? Come in, invece di controllare solo per 0, posso anche confrontare questi valori con un'altra variabile, ad esempio un int chiamato 'c'? – Amndeep7

+0

Nah, funziona solo se entrambi sono zero. –

+1

Non funziona - se 'a = 1; b = 0; ', il test fallisce, il test originale passa. – Mat

0

Non esiste una sintassi speciale per questo. Potresti fare una funzione per quello. Supponendo almeno Java 1.5:

public <T> boolean eitherOneEquals(T o1, T o2, T expectedValue) { 
    return o1.equals(expectedValue) || o2.equals(expectedValue); 
} 

if(eitherOneEquals(o1, o2, expectedValue)) { 
    // do something... 
} 
2
if(a == 0 || b == 0) 
{ 
//Then do something 
} 

Perché non tenerlo leggibile? Che cos'è lo non conciso a riguardo? D'altra parte,

a = (int)(Math.random()*5); 

comporta un cast non necessario. Perché non usare semplicemente Random e invocare nextInt()?

+0

Non ero mai a conoscenza di quella classe, mi era sempre stato insegnato a usare Math.random() soprattutto perché può diventare facilmente adattabile all'intervallo di valori che desidero creare – Amndeep7

+1

È facile impostare il range dei valori utilizzando Random, ad esempio un numero casuale compreso tra 1-6: 1 + myRand.nextInt (5); –

1

Anche se si è usato l'operazione a bit come suggerito Ted, le espressioni non sono uguali, in quanto si richiede almeno uno delle variabili a zero e il secondo richiede sia di loro di essere pari a zero .

Per quanto riguarda la domanda, non esiste tale scorciatoia in Java.

2

Per questo esempio, si può fare

if (a * b == 0) 

o per più variabili

if (a * b * c * d == 0) 

mentre più concisa potrebbe non essere il più chiaro. Per valori superiori, è necessario eseguire il cast su long per evitare un overflow.

+1

Potresti aver bisogno di qualcosa di più grande di un lungo per più di due variabili, se possono essere tutte dell'intero intervallo .. – harold

+0

Molto vero. Per i tipi più grandi devi controllare ognuno di essi, ma per valori '0 - 4' dovrebbe essere sicuro . –

2

È possibile inserire gli interi in un set e vedere se contiene il valore specificato. Using Guava:

if(newHashSet(a, b).contains(0)){ 
    // do something 
} 

Ma due semplici paragoni int sono probabilmente più facile da capire in questo caso.

1

Si può provare questo codice:

public static boolean match (Object ref, Object... objects) 
{ 
    if (ref == null) 
     return false; 
    // 
    for (Object obj : objects) 
     if (obj.equals (ref)) 
      return true; 
    // 
    return false; 
} // match 

Quindi, se è possibile controllare in questo modo:

if (match (reference, "123", "124", "125")) 
    ; // do something 
2

Ecco una modifica della risposta @ di Buc che può assumere qualsiasi numero di argomenti:

public <T> boolean oneOfEquals(T expected, T... os) { 
    for (T o : os) { 
     if (expected.equals(o)) return true; 
    } 
    return false; 
} 
11

È possibile effettuare quanto segue in plain java

Arrays.asList(a, b, c, d).contains(x); 
1

As referenced from this answer:

In Java 8 +, è possibile utilizzare un Stream e anyMatch. Qualcosa di simile

if (Stream.of(b, c, d).anyMatch(x -> x.equals(a))) { 
    // ... do something ... 
} 

Nota che questo ha la possibilità di correre più lento rispetto agli altri se i controlli, a causa del sovraccarico di avvolgere questi elementi in un torrente per cominciare.

Problemi correlati