2011-09-30 7 views
36

Proste pytanie, ale Google niewiele pomagał.Najlepszy sposób na sformatowanie wielu warunków "lub" w instrukcji if (Java)

mam if z wieloma warunkami (trzeba sprawdzić na 10 lub 15 stałych aby sprawdzić, czy któryś z nich są obecne).

Zamiast pisać coś takiego:

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

jest tam dowolny sposób formatować je jak

if x is [12, 16, 19]? 

prostu zastanawiasz się, czy istnieje prostszy sposób, aby zakodować to, każda pomoc mile widziana.

Edit: Odpowiedzi były bardzo pomocne, ale poproszono mnie, aby dodać więcej szczegółów o kilka osób, więc zrobię to, aby zaspokoić swoją ciekawość. Tworzyłem klasę walidacji dat, która wymagała upewnienia się, że dni nie były> 30 w miesiącach, które mają tylko 30 dni (z których 4 jest, jak myślę) i pisałem instrukcję if, aby sprawdzić takie rzeczy:

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

Zastanawiałem się, czy istnieje szybszy sposób kodowania takich rzeczy - wiele z poniższych odpowiedzi pomogło :).

+0

Czy możesz podać lepszy przykład tego, co próbujesz zrobić? Może rozwiązanie polega na tym, by o tym myśleć? –

Odpowiedz

37

Używam tego rodzaju wzoru często. Jest bardzo kompaktowy:

// 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)) { 
    ... 
} 

HashSet używany jest tutaj, aby dać dobre wyniki look-up - nawet bardzo duże zestawy hash są w stanie wykonać bardzo szybko .

Jeżeli wydajność nie jest ważne, można kodować sens go w jednej linii:

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

ale wiem, że będzie tworzyć nową ArrayList za każdym razem wykonuje.

+2

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

+0

Brian, dodałem twoją propozycję z zastrzeżeniem wydajności – Bohemian

+1

Wolałbym użyć 'Set' niż' List' do tego, ale to nie będzie miało żadnego wpływu na te kilka elementów. –

3

Można wyszukać obecność klucza mapy lub sprawdzić, czy jest w zestawie.

W zależności od tego, czego faktycznie robi, choć, może być trudny do rozwiązania problemu złym :)

3

użyć zbiór jakiegoś - będzie to uczynić kod bardziej czytelnym i ukrycia od wszystkich te stałe. Prostym sposobem byłoby z listy:

// 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 
} 

Jak czeska punktów na liście stałych mogą być statyczne, więc jest to dostępne w więcej niż jednym miejscu.

Dla wszystkich zainteresowanych lista w moim przykładzie jest używana pod numerem double brace initialization. Odkąd wpadłem na to ostatnio, znalazłem to miłe w pisaniu szybkich inicjalizacji listy brudnych &.

+1

lub 'if (Arrays.asList (nowy int [] {12,16,19}). Zawiera (x)) {...}' –

+0

@Bala pewnie! W każdym razie lista jest tylko przykładem kolekcji do wykorzystania tutaj. Jak jedna z innych odpowiedzi sugeruje, że zbiór może być lepszy, aby zapewnić stałe są unikalne ... Lub tablica skrótów, aby przyspieszyć wyszukiwanie itp. –

10

Czy chcesz przejść do tego?

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

Jeżeli zbiór możliwości jest „zwarty” (to największa wartość - najmniejsza wartość wynosi, powiedzmy, mniej niż 200) można rozważyć tabeli odnośników. Byłoby to szczególnie przydatne, jeśli miała strukturę jak

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

Utwórz tablicę z wartościami identyfikacji gałęzi należy podjąć (1, 2, 3 w powyższym przykładzie), a następnie Twoje testy stać

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

To, czy jest to odpowiednie, zależy od semantyki problemu.

Jeśli tablica nie jest odpowiednia, można użyć numeru Map<Integer,Integer>, lub jeśli chcesz przetestować członkostwo dla pojedynczej instrukcji, zrobi to Set<Integer>.To dużo siły ognia dla prostej deklaracji if, więc bez większego kontekstu trudno jest poprowadzić cię we właściwym kierunku.

4

Nie można tego zrobić w Javie. można jednak napisać metodę, co następuje:

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

Z Java 8, można użyć prymitywny strumieniowe:

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

ale może to mieć niewielki narzut (lub nie), w zależności od liczby porównań.

Powiązane problemy