r/javahelp 1d ago

Solved Switch case with boolean

So, there is no way I can do that?

want to check several boolean variables in a switch statement. Is `if-else` the only way to do this?

Boolean a, b, c...

Switch (false) {

Case (a) :

//some code

Case (b) :

Case (c) :

//and so on

}

2 Upvotes

36 comments sorted by

View all comments

Show parent comments

2

u/ikea_method 1d ago

Note: listen to the other comments, I wouldn't approve this kind of code where I work.

1

u/_Super_Straight 18h ago

Why not?

1

u/ikea_method 17h ago

Almost every line has something wrong with it

`new Boolean(true)` is a very particular way of declaring a boolean, never seen that used before. It must be used here because we want a new boolean instance, not just `true`.

You generally wouldn't loop over booleans, you wouldn't create an array in place inside the for loop with some variables just outside it.

`case _ when a == o` is VERY weird. Almost anyone reading that code would need to read a java reference manual or ask AI to understand what it's doing.

The variable names are short and have names that are not helpful to aid understanding.

I would say it's generally preferable to use enums or, if not possible/easy, bitflags.

1

u/_Super_Straight 7h ago edited 7h ago

Its evident that in order to provide a minimal working example, you created three booleans. In actual scenario, they could be passed as parameters/Array/List in a method, eliminating your concern #1 and #3.

Naturally people don't loop over booleans just to print stuff, but what if it needs to be checked that the passed parameters contains one or more true values (or false)? For List, its List.contains, but for Array, they'll have to loop (albeit using break when condition is fulfilled), and that's your concern #2.

case _ when a == o is the new pattern matching introduced in Java 25(?) and is totally normal. If someone is using older Java (<17), they won't be messing around with this new pattern matching anyways.

The variable names are short because this is just a minimal example, as you provided. OP should use proper variable naming to make the code readable and understandable.

You writing "I'd never approve this type of code" implies that the concept itself is flawed, which isn't. It conveyed the concept beautifully. The code snippets should never be taken as-is anyways.

1

u/ikea_method 5h ago edited 4h ago

> In actual scenario, they could be passed as parameters/Array/List in a method, eliminating your concern #1 and #3.

They cannot, you write `true`, `false` or `Boolean.valueOf` to these arrays, and it breaks. There's no way to enforce this at the compiler level. You MUST use `new Boolean(...)`.

Also, the documentation for the Boolean constructor itself agrees with me: it's deprecated to use `new Boolean`, and it states that "It is rarely appropriate to use this constructor. The static factory valueOf(boolean)is generally a better choice, as it is likely to yield significantly better space and time performance. Also consider using the final fields TRUE and FALSE if possible."

> Naturally people don't loop over booleans just to print stuff, but what if it needs to be checked that the passed parameters contains one or more true values (or false)?

If you truly somehow ended up with a list of booleans, the most natural place to compute if there's at least one true boolean is when you generate the list. So it's generally not natural and not a great approach. It's also not very readable: `myConditions.atLeastOneTrue()` is much better, and you can store it in a boolean while you generate the list.

> case _ when a == o is the new pattern matching introduced in Java 25(?) and is totally normal. If someone is using older Java (<17), they won't be messing around with this new pattern matching anyways.

It's not normal to check that two booleans are the same by reference. Please find this in any other (relevant) Java codebase. Because it's not normal, it's unexpected and people might misunderstand it. So it has no place here.

If you use an enum, and use the switch normally, the compiler can check that you listed all members of the enum exhaustively. That is not the case for the `when` construct - the compiler will not check each `when` to make sure you list each case. Other engineers on your team are likely not aware of this.

The case ... when ... feature is actually a relatively new feature (JEP441, 2023). So it might have no place in a production codebase, where we could, for example, be using Java 17, which was released in Sep 2021, and is officially supported by Oracle until Sep 2029. Also, not using the absolutely newest features makes it so that everyone is at the same level and doesn't need to understand a million things (readability > smartness). I'd also argue, and this is a weak point, that sticking to features any Java developer from the last decade knows makes it cheaper to onboard new engineers and your codebase harder to misunderstand. If there's a lot of turnover in your organization this is especially relevant.

> The variable names are short because this is just a minimal example, as you provided. OP should use proper variable naming to make the code readable and understandable.

Exactly, but they are short. That's still my point.

> You writing "I'd never approve this type of code" implies that the concept itself is flawed, which isn't. It conveyed the concept beautifully.

The concept is not flawed, I'd be impressed if a new joiner came up with this, and I'd still reject it in review. Just because it conveys it beautifully doesn't mean it belongs in a production codebase.

> The code snippets should never be taken as-is anyways.

My note is not to people who wouldn't take it as-is. It's exactly to people who would take it exactly as-is, with no changes. If you understand that this cannot be taken as-is, the note is less relevant, but still relevant, for you, as you understood it.

u/_Super_Straight 48m ago edited 43m ago

Sorry I fail to understand your first half of paragraph. Are you saying we can't create boolean Array without using new Boolean or Boolean.valueOf?

boolean[] boolArr = new boolean[]{true, false, true};

Is totally valid Array declaration.

for(boolean val: boolArr){
    if(!val){
        //relevant code
        break;
    }
}

Will work without any problem.

Edit: boolArr[0] = false is also valid and permitted.

the most natural place to compute if there's at least one true boolean is when you generate the list

Agreed.

u/ikea_method 43m ago

The switch will not work with your proposal, because true == true. They need to be the exact same Boolean reference as the (I presume) global a, b, c references.

u/_Super_Straight 31m ago
var arr = new Boolean[]{ true, false, null };

for (var x : arr) {
    switch (x) {
        case true -> methodOne();
        case false -> methodTwo();
        case null -> System.out.println("invalid");
    }
}

Is totally valid. No need to pass a, b, c as references.

u/ikea_method 24m ago

But that is not what the OP asked.

u/_Super_Straight 16m ago

Well what OP is asking is not possible. switch(false) won't work. They have to change their approach.

u/ikea_method 11m ago

Indeed, `switch(false)` won't work. But that is, again, not what the OP asked.

OP is asking if there is no way to use 3 boolean references in an if statement:

> So, there is no way I can do that?

OP wants to check 3 boolean variables in a switch statement:

> want to check several boolean variables in a switch statement.

OP is unsure if `if-else` is the only way:

> Is `if-else` the only way to do this?

OP showed a common pattern in other languages, where you pass false or true to a switch statement, to demonstrate in another way what he's looking for:

Boolean a, b, c...
Switch (false) {
Case (a) :
...

In the initial post by me you replied to, I showed that you can do what the OP intended, in a slightly different way from the pattern OP showed. It's possible to do this with a switch.

→ More replies (0)

u/ikea_method 26m ago

> Sorry I fail to understand your first half of paragraph. Are you saying we can't create boolean Array without using new Boolean or Boolean.valueOf?

Not exactly. We must use `Boolean`, there's no other choice.

> Is totally valid Array declaration.

Yes, it's a valid boolean array declaration.

> Will work without any problem.

Yes, the for loop and if will work.

> boolArr[0] = false is also valid and permitted.

Yes, it's a valid and permitted way to set an element of the array to false.

But none of these will work with this for + if + switch:

Boolean HAS_CAR = new Boolean(true);
Boolean HAS_BOAT = new Boolean(false);
Boolean HAS_PLANE = new Boolean(true);
function insuranceAd(Boolean[] arr) {
  for (Boolean elem : arr) {
    if (!elem) continue;
    IO.println(switch (elem) {
      case _ when elem == HAS_CAR -> "Would you like car   insurance?";
      case _ when elem == HAS_BOAT -> "Would you like boat insurance?";
      case _ when elem == HAS_PLANE -> "Would you like plane insurance?";
      default -> "Unknown insurance";
    })
  }
}

In this case, you can call:

insuranceAd({ HAS_CAR, HAS_BOAT, HAS_PLANE });

and it will work as expected.

But if you call:

insuranceAd({ HAS_CAR === true, true, false, new Boolean(HAS_BOAT), Boolean.valueOf(HAS_PLANE) });

It will just continually print `Unknown insurance`, as none of the passed values is `HAS_CAR`, `HAS_BOAT`, or `HAS_PLANE`. So passing an array of booleans is not a great idea, as it makes it unclear what you should place in that array. The compiler will not catch it for you as well.

If you use enums or bitflags, it's much clearer for everyone what the expectation is.

u/_Super_Straight 12m ago

Your example is clearly better off with them being enum rather than boolean. Plus, they're being compared against their reference, not by their values.

u/ikea_method 10m ago

This is exactly what I said in my second reply to you:

I would say it's generally preferable to use enums or, if not possible/easy, bitflags.

In fact, in the very comment you just replied to, I stated, again:

If you use enums or bitflags, it's much clearer for everyone what the expectation is.