Is it possible to have a switch-case statement with more than a variable in groovy? I tried with tuples but the case part doesn't accept more than one argument.
I am trying to avoid several nested if statements so instead of
if (a==1) {
if (b==2) {
if (c==3) {
// do something
}
}
}
else {
if (a==4) {
if (b==5) {
if (c==6) {
//do something else
}
}
}
}
Can I do:
switch(a,b,c) {
case : (1,2,3) // if a==1, b==2 and c==3
// do something
...
case : (4,5,6)
// do something else
...
}
}
Groovy is just dirty java, you don't need any class definition. everything you write in a java method you can write it directly in groovy.
switch (num) {
case 1:
case 2:
case 3:
System.out.println("1 through 3");
break;
case 6:
case 7:
case 8:
System.out.println("6 through 8");
break;
}
To answer your question, inside the switch we need an expression, not function parameters.
Based on your edit, I believe that this should work:
if (a == 1 && b == 2 && c == 3) {
// do something
} else if (a == 4 && b == 5 && c == 6) {
// do something else
}
If you want a switch statement instead, that's possible:
def val = [a, b, c]
switch (val) {
case {it == [1, 2, 3]}:
// something
break;
case {it == [4, 5, 6]}:
// something else
break;
class Solution{
static void main (String...args){
BufferedReader br=new BufferedReader(new
InputStreamReader(System.in))
def val=br.readLine()
switch(val){
case('E0'):
println "Basic"
break;
default:
break;
case('E1'):
println "Inter"
break;
case('E2'):
println "Advance"
break;
default:
println "not defined"
}
}
}
Related
I know it's possible to express AND logic between if let statement and a condition like this
if let (Some(a), true) = (b, c == d) {
// do something
}
But what if I need an OR logic?
if let (Some(a)) = b /* || c == d */ {
// do something
} else {
// do something else
}
The only way I figure it out is as follows, but I think it's a little bit ugly as I have to write some code twice
if let (Some(a)) = b {
// do something
} else if c == d {
// do something
} else {
// do something else
}
If you have the same "do something" code in both cases then it must not use a. In that case you can use is_some:
if b.is_some() || c == d {
// do something
} else {
// do something else
}
In the more general case, you can use matches! to check if b matches a pattern without creating any bindings:
if matches!(b, Some(_)) || c == d {
// do something
} else {
// do something else
}
My problem is that my switch (case) statement keeps evaluating an extra switch case statement. And I don't understand why it's doing this.
My problem is in case 10:
It's always being evaluated, doesnt matter what case # i choose. It will always run to case 10: and evaluate if it's true or not.
I'v been going over it and I don't understand what's going on. Why would it read case 10.
public boolean checkIfPossible(double x, double a, double y) {
boolean pass;
int value = spinnerA.getSelectedItemPosition();
switch (value) {
case 1:
if (x > a && a == 0) {
etX.setError("Error1 ");
pass = false;
break;
} else if (x == a) {
etX.setError("Error2);
pass = false;
break;
}
case 10:
if (x == y) {
etX.setError("Error3");
pass = false;
break;
}
default:
pass = true;
}
return pass;
}
The solution to your problem is to put a break statement after your if and else statements in your case 1 like this:
case 1:
if (x > a && a == 0) {
etX.setError("Error1 ");
pass = false;
}
else if (x == a) {
etX.setError("Error2);
pass = false;
}
break;
The most likely reason you are having this problem is because the conditions for your if and else-if are both not satisfied. There is no break statement to stop the flow (since the if and else-if blocks are not executed). That's why your code eventually spills over to the next case. Try logging the value of x and a to verify.
I hope this helps.. Merry coding!
I'm having a bit of trouble getting a few parts of my code to work properly.
I'm still a bit new to java and could some direction and clues to where I went wrong.
The error comes from the if statements. I feel like i know why they are erring out because the || are undefined but I'm not sure how to fix it. What I'm trying to get it to do is take the inputs either L,R,F,B (left, right, forward and back). lowercase the input and either accept either one or the other using boolean "or".
import java.util.Scanner;
public class ChooseYourAdventure {
public static void main(String[]args) {
Scanner input = new Scanner(System.in);
System.out.print("Choose a diection: ");
String direction = input.nextLine().toLowerCase();
System.out.printf(" %s and %s/n",getDirection (way),getYourChoice (found));
}
public static String getYourChoice (String found) {
String result = "Unknown";
switch (found)
{
case "l":
result = " now we all know you can turn left unlike Zoolander";
break;
case "left":
result = " now we all know you can turn left unlike Zoolander";
break;
case "r":
result = " you fall down a hole never to be seen again... sad.";
break;
case "right":
result = " you fall down a hole never to be seen again... sad.";
break;
case "f":
result = " YOU ARE THE KWISATZ HADERACH!!";
break;
case "forward":
result = " YOU ARE THE KWISATZ HADERACH!!";
break;
case "b":
result = " you are a scaredy cat but, you live to fight or runaway another day";
break;
case "back":
result = " you are a scaredy cat but, you live to fight or runaway another day";
break;
}
return result;
}
public static String getDirection(String way) {
String result;
if (way == "l" || "left") {
System.out.print("Your character moves left");
}
else if (way == "r" || "right") {
System.out.println("You character moves right");
}
else if (way == "f" || "forward") {
System.out.println("Your character moves forward");
}
else if (way == "b" || "back") {
System.out.println("Your character moves forward");
}
else {
System.out.println(" You cant go that way ");
}
return result;
}
}
All your if statements are wrong. When using || or &&, you need to specify the variable way on each side of the ||:
if (way == "l" || way == "left") {
System.out.print("Your character moves left");
}
My intention is to let the user decide which method to use by cheking its input.
I have the following code:
try {
String test = scan.next();
if(test == "y") {
//do stuff
}
else if (test == "n") {
//do stuff
}
} catch (Exception e) {
System.out.println("false");
}
I tried to analyze with the debugger. It is not jumping in the if-statement.
can you help me out here?
You need to use equals to compare strings
if(test == "y")
becomes
if (test.equals("y"))
Same for "n" obviously.
== test for reference equality, but you're looking for value equality, that's why you should use equals, and not ==.
This is what I'd like to do:
class MyObject {
#Lazy volatile String test = {
//initalize with network access
}()
}
def my = new MyObject()
println my.test
//Should clear the property but throws groovy.lang.ReadOnlyPropertyException
my.test = null
//Should invoke a new initialization
println my.test
Unfortunately lazy fields are readonly fields in Groovy and clearing the property leads to an exception.
Any idea how to make a lazy field reinitializable without reimplementing the double checking logic provided by the #Lazy annotation?
UPDATE:
Considering soft=true (from the 1st answer) made me run a few tests:
class MyObject {
#Lazy() volatile String test = {
//initalize with network access
println 'init'
Thread.sleep(1000)
'test'
}()
}
def my = new MyObject()
//my.test = null
10.times { zahl ->
Thread.start {println "$zahl: $my.test"}
}
Will have the following output on my Groovy console after approx 1 sec:
init
0: test
7: test
6: test
1: test
8: test
4: test
9: test
3: test
5: test
2: test
This is as expected (and wanted). Now I add soft=trueand the result changes dramatically and it takes 10 seconds:
init
init
0: test
init
9: test
init
8: test
init
7: test
init
6: test
init
5: test
init
4: test
init
3: test
init
2: test
1: test
Maybe I'm doing the test wrong or soft=true destroys the caching effect completely. Any ideas?
Can't you use the soft attribute of Lazy, ie:
class MyObject {
#Lazy( soft=true ) volatile String test = {
//initalize with network access
}()
}
edit
With soft=true, the annotation generates a setter and a getter like so:
private volatile java.lang.ref.SoftReference $test
public java.lang.String getTest() {
java.lang.String res = $test?.get()
if ( res != null) {
return res
} else {
synchronized ( this ) {
if ( res != null) {
return res
} else {
res = {
}.call()
$test = new java.lang.ref.SoftReference( res )
return res
}
}
}
}
public void setTest(java.lang.String value) {
if ( value != null) {
$test = new java.lang.ref.SoftReference( value )
} else {
$test = null
}
}
Without soft=true, you don't get a setter
private volatile java.lang.String $test
public java.lang.String getTest() {
java.lang.Object $test_local = $test
if ( $test_local != null) {
return $test_local
} else {
synchronized ( this ) {
if ( $test != null) {
return $test
} else {
return $test = {
}.call()
}
}
}
}
So the variable is read-only. Not currently sure if this is intentional, or a side-effect of using soft=true though...
Edit #2
This looks like it might be a bug in the implementation of Lazy with soft=true
If we change the getter to:
public java.lang.String getTest() {
java.lang.String res = $test?.get()
if( res != null ) {
return res
} else {
synchronized( this ) {
// Get the reference again rather than just check the existing res
res = $test?.get()
if( res != null ) {
return res
} else {
res = {
println 'init'
Thread.sleep(1000)
'test'
}.call()
$test = new java.lang.ref.SoftReference<String>( res )
return res
}
}
}
}
I think it's working... I'll work on a bugfix