Is there a way to make boolean expressions like "a == b || a == с || a == d" more succinct?

Is there a way to make boolean expressions like “a == b || a == с || a == d” more succinct? Something like “a == b || с || d”. Suppose there’s an array of Latin letters and you want to filter out certain letters (I know it’s not how the OR operator works in Java!)

char[] alphabet = new char[26];
for (int i = 0; i < alphabet.length; i++) {
alphabet[i] = (char)('A' + i);
}
ArrayList<Character> specialLetterList = new ArrayList<>();
for (char letter : alphabet) {
if (letter.toLowerCase == 'c' || 'd' || 'e' || 'o') {
specialLetterList.add(letter);
}
}

Or suppose there are objects, and you want to make sure that only objects with certain field values pass through an if statement

String hairColor;
public Person(String hairColor){
this.hairColor = hairColor;
}
public static void main (String[] args) {
List<Person> individuals = Arrays.asList (
Person individual1 = new Person("blonde");
Person individual2 = new Person("ginger");
Person individual3 = new Person("dark");
)
List<Person> individualsWithFancyHairColor = new List<>();
for (Person person : individuals) {
if (person.hairColor.equals("blonde" || "ginger")) {
individualsWithFancyHairColor.add(person);
}
}
}

Or suppose I want to retrieve certain letters from a List of Characters by their Unicode values. I could do it like this, but it’s verbose

List<Character> specialLetters = englishAlphabet.stream()
               .filter(letter -> (int)Character.toUpperCase(letter) == 67
                                    || (int)Character.toUpperCase(letter) == 79
                                    || (int)Character.toUpperCase(letter) == 68
                                    || (int)Character.toUpperCase(letter) == 69)
                .toList();

How do I express the “OR” idea more succinctly here?

No, this has been asked (and answered) many times before.

The “OR” operator || compares the expressions either side of it to determine whether they are truthy or falsey, and thus by extension whether the result of the operation is true or false.

If you have a conditional expression of a == b, you’re testing is a equal to b. Same for a == c.

When we do a == b || a == c we are asking, essentially, “is a equal to b, or is a equal to c?” If either of those are true, the expression is true.

The expression a == b || a == c is not equivalent to a == b || c. The latter is asking "is a equal to b, or is c true? If c is a “truthy” value, then your whole expression is true regardless of whether a == c as you intended.

Depending on the circumstance, you may be able to leverage pre-existing Java class methods to do what you’re after with less typing of == by using something like List.contains() or by doing a search over an array for example.

6 Likes

Look, I know it’s not how the OR operator works. My question was whether the same goal could be achieved with the tools Java actually provides. Imagine there were 10 or 20 different “fancy” hair colors instead of two. There’s no way any sane person would ever decide to list them all in an if argument in such a verbose way. There must be shortcuts. How would you rewrite my examples to make them more succinct in cases like that?

You could consider using switch...case statements, but I imagine that’s not really what you’re looking for?

Please rewrite my examples using the switch statements to show what you mean

Of which, I gave you two examples: the contains() method for the List type probably being the most directly applicable to the examples you gave.

No, they probably wouldn’t… especially not if there were a total of 25 colours, of which 20 were - as you put it - “fancy” and the remainder “uninteresting”. At which point, the filter would not necessarily be to look for the 20 values of interest but to look for the 5 which aren’t and exclude them…

I dislike the word “shortcuts”, mainly from a semantic view point as it implies cut corners and by extension shoddy code, but yes in any program there will likely always be ways to make it more efficient.

I’m not going to rework your examples - mainly because neither of them immediately run for me without compiler errors. Instead, consider how the following may be of use in certain situations beyond the hypothetical ones you’ve constructed.

(Again, I’m mainly concerned with briefly introducing the List.contains() class method. No idea if this actually runs in the context of your example.)

...
List<String> interestingHairColours(Arrays.asList("blonde", "ginger");
for (Person person : individuals) {
  if (interestingHairColours.contains(person.hairColor) {
    // the person's hair colour is of interest... so do something.

}
...
1 Like

The first two weren’t supposed to be compiled, by the way. I purposefully used “OR” operators in a way that is not supported by Java to get my idea across. The third is just a code snippet, it is not supposed to be compiled either (otherwise, there’s nothing wrong with it). Thanks for your idea with Lists, though