Ken Hall
Ken Hall

Reputation: 127

In Java, is there a cleaner approach to an if statement with a slew of ||'s

I know this question is basic but I am looking for a less-clumsy approach to the following if statement:

if ((sOne.Contains('*')) || (sOne.Contains('/')) || (sOne.Contains('-')) || (sOne.Contains('+')) || (sOne.Contains('%'))){ 

I should also note that sOne.Contains() refers to the following code...

public boolean Contains(char key) {
    // Checks stack for key
    boolean retval = arrs.contains(key);
    return retval;

}

It should also be noted that those five chars will never be changed.

Upvotes: 6

Views: 201

Answers (7)

gyre
gyre

Reputation: 16779

You could use a breaking for-each loop over a character array:

for (char c : "*/-+%".toCharArray()) {
    if (sOne.Contains(c)) {
        // ...
        break;
    }
}

If you're extremely concerned about performance you might also want to pull out the toCharArray() call and cache the result in a static final char[] constant.

You could even use this strategy to define other convenience methods on your sOne object, like ContainsAny or ContainsAll (credit to Sina Madrid for the name ContainsAny):

public boolean ContainsAny (CharSequence keys) {
    for (int i = 0; i < keys.length; i++)
        if (Contains(keys.charAt(i)) return true;

    return false;
}

public boolean ContainsAll (CharSequence keys) {
    for (int i = 0; i < keys.length; i++)
        if (!Contains(keys.charAt(i)) return false;

    return true;
}

Usage would look something like this:

if (sOne.ContainsAny("*/-+%")) {
    // ...
}

Upvotes: 6

Boann
Boann

Reputation: 50010

If you're using an if statement of this form in only one place, it would be fine to keep the same structure but just format it more neatly:

if (sOne.contains('+') ||
    sOne.contains('-') ||
    sOne.contains('*') ||
    sOne.contains('/') ||
    sOne.contains('%')) {
    ...
}

P.S. In your method it is not necessary to define a boolean variable merely to immediately return it; you can return the other method's result directly:

public boolean contains(char key) {
    // Checks stack for key
    return arrs.contains(key);
}

Please also note the naming conventions: method names (contains) should start with a lower-case letter.

Upvotes: 0

Sina Madani
Sina Madani

Reputation: 1324

You could write a method like this and still re-use your existing method (substitute T for type of sOne):

static <T> boolean ContainsAny(T sOne, char... keys) {
    for (char key : keys) {
        if (sOne.Contains(key))
            return true;
    }
    return false;
}

You can then invoke it like so with any number of characters to evaluate:

if (ContainsAny(sOne, '%', '_', '-')) {
    //code here
}

Upvotes: 1

Jere
Jere

Reputation: 601

You don't show what arr is but since it has a contains method I'm going to assume it is a collection. So if you were to put your keys into a static collection like a Set and if arr is a collection of some type as well, you could use Collections.disjoint. disjoint returns true if there is no intersection between two collections.

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

public class Test {
  static Set<Character> keys = new HashSet<Character>(Arrays.asList('*','/','-','+','%'));

  static class SOne {
    Set<Character> arrs = null;
    SOne(String line) {
      arrs = line.chars().mapToObj(e->(char)e).collect(Collectors.toSet());
    }
    public boolean Contains(Set<Character> checkset) {
      return !Collections.disjoint(arrs, checkset);
    }
  }

  static public void main(String args[]) {
    SOne sOne = new SOne("Does not contain");
    SOne sTwo = new SOne("Does contain a + sign");

    if(sOne.Contains(keys)) {
      System.out.println("Fail: Contains a key");
    } else {
      System.out.println("Pass: Does not contain a key");
    }

    if(sTwo.Contains(keys)) {
      System.out.println("Pass: Contains a key");
    } else {
      System.out.println("Fail: Does not contain a key");
    }
  }
}

Upvotes: 1

xehpuk
xehpuk

Reputation: 8241

Somewhere, you need the characters in a list:

List<Character> keys = Arrays.asList('*', '/', '-', '+', '%');

And then you can do:

if (keys.stream().anyMatch(sOne::Contains)) {

Upvotes: 4

Trash Can
Trash Can

Reputation: 6814

You can try using regular expression like this

if (sOne.matches(".*[-*/+%].*")) {
  // your code
}

Upvotes: 4

Hendrik
Hendrik

Reputation: 360

How about this method: Items are your keys stored in an Array.

public static boolean stringContainsItemFromList(String inputStr, String[] items)
{
    for(int i =0; i < items.length; i++)
    {
        if(inputStr.contains(items[i]))
        {
            return true;
        }
    }
    return false;
}

Upvotes: 1

Related Questions