Best way to format multiple 'or' conditions in an if statement

JavaSyntaxIf Statement

Java Problem Overview


I have an if statement with many conditions (have to check for 10 or 15 constants to see if any of them are present.)

Instead of writing something like:

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

is there any way to format it like

if x is [12, 16, 19]?

Just wondering if there is an easier way to code this, any help appreciated.

The answers have been very helpful, but I was asked to add more detail by a few people, so I will do that to satiate their curiosity. I was making a date validation class that needed to make sure days were not > 30 in the months that have only 30 days (of which there are 4, I think) and I was writing an if statement to check things like this:

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

I was just wondering if there was a faster way to code things like that - many of the answers below have helped.

Java Solutions


Solution 1 - Java

I use this kind of pattern often. It's very compact:

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

A HashSet is used here to give good look-up performance - even very large hash sets are able to execute contains() extremely quickly.

If performance is not important, you can code the gist of it into one line:

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

but know that it will create a new ArrayList every time it executes.

Solution 2 - Java

Do you want to switch to this??

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

Solution 3 - Java

You could look for the presence of a map key or see if it's in a set.

Depending on what you're actually doing, though, you might be trying to solve the problem wrong :)

Solution 4 - Java

Use a collection of some sort - this will make the code more readable and hide away all those constants. A simple way would be with a list:

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

As Bohemian points out the list of constants can be static so it's accessible in more than one place.

For anyone interested, the list in my example is using double brace initialization. Since I ran into it recently I've found it nice for writing quick & dirty list initializations.

Solution 5 - Java

If the set of possibilities is "compact" (i.e. largest-value - smallest-value is, say, less than 200) you might consider a lookup table. This would be especially useful if you had a structure like

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

Set up an array with values identifying the branch to be taken (1, 2, 3 in the example above) and then your tests become

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

Whether or not this is appropriate depends on the semantics of the problem.

If an array isn't appropriate, you could use a Map<Integer,Integer>, or if you just want to test membership for a single statement, a Set<Integer> would do. That's a lot of firepower for a simple if statement, however, so without more context it's kind of hard to guide you in the right direction.

Solution 6 - Java

No you cannot do that in Java. you can however write a method as follows:

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

Solution 7 - Java

With Java 8, you could use a primitive stream:

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

but this may have a slight overhead (or not), depending on the number of comparisons.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnthonyView Question on Stackoverflow
Solution 1 - JavaBohemianView Answer on Stackoverflow
Solution 2 - JavaMarsellus WallaceView Answer on Stackoverflow
Solution 3 - JavaDave NewtonView Answer on Stackoverflow
Solution 4 - Javafilip-fkuView Answer on Stackoverflow
Solution 5 - JavaJim GarrisonView Answer on Stackoverflow
Solution 6 - JavafastcodejavaView Answer on Stackoverflow
Solution 7 - JavaassyliasView Answer on Stackoverflow