How to execute code based on integer value - java

I have an int, int minion1Hp, which can be a value of 0 -> 20. Depending on the value it is, a certain image resource will be set for an ImageView, using bar1.setImageResource(R.drawable.hpa);. However, my code currently looks like this:
if (minion1Hp == 0) {
bar1.setImageResource(R.drawable.hp);
}
if (minion1Hp == 1) {
bar1.setImageResource(R.drawable.hpa);
}
if (minion1Hp == 2) {
bar1.setImageResource(R.drawable.hpb);
}
if (minion1Hp == 3) {
bar1.setImageResource(R.drawable.hpc);
}
if (minion1Hp == 4) {
bar1.setImageResource(R.drawable.hpd);
}
if (minion1Hp == 5) {
bar1.setImageResource(R.drawable.hpe);
}
... and so on. Is there a more efficient way of doing this, rather than a long list of if statements?

Suggestion: initialize a map at startup (say in onCreate()). Like this:
mDrawables = new HashMap<Integer, Integer>();
mDrawables.put(0, R.drawable.hp);
mDrawables.put(1, R.drawable.hpa);
...
then just do:
bar1.setImageResource(mDrawables.get(minion1Hp));

You can use a switch statement with a separate case for each instance. On a side note, you shouldn't be using just if statements up there, your code will run slowly, you should be using else if to make it run faster (since your hp can never be 1 and 2 at the same time.
Ex for switch statements:
switch (minion1Hp){
case 1:
bar1.setImageResource(R.drawable.hp);
break;
case 2:
bar1.setImageResource(R.drawable.hpa);
break;
etc.
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

An improvement here would be to change each if after the first one to an else if as minion1Hp can't be multiple values at the same time, but you might find it slightly neater to have the whole thing in a switch-case block instead.

Related

How do I switch between two views being visible?

I am making an application that helps score a table tennis game. I am at the final stages but I am having trouble with switching the server around every two points. I have given it a lot of thought but I can only get it to switch once. I know it is probably an easy solution but it's just not coming to me.
Here's how I am switching it once. I am using a count each time the button is pressed and when it reaches a number divisible by 2 it switches to the right.. However, using this logic is making it difficult to switch back! Thanks in advance.
public void serveSwitch() {
TextView leftServe = findViewById(R.id.leftServe);
TextView rightServe = findViewById(R.id.rightServe);
serverCount++;
if (server.serve=="left") {
if (serverCount % 2 == 0) {
rightServe.setVisibility(View.VISIBLE);
leftServe.setVisibility(View.GONE);
}
}
The part I'm struggling with is the logic on how to switch visibility every two points
If I get your point right, you want to toggle the visibility from off to on every two points and vice versa
You can do something like:
...
if (server.serve=="left") {
if (serverCount % 2 == 0) {
switch (rightServe.getVisibility()) {
case View.GONE:
rightServe.setVisibility(View.VISIBLE);
break;
case View.VISIBLE:
rightServe.setVisibility(View.GONE);
break;
}
switch (leftServe.getVisibility()) {
case View.GONE:
leftServe.setVisibility(View.VISIBLE);
break;
case View.VISIBLE:
leftServe.setVisibility(View.GONE);
break;
}
}
}
Note: I left the equality as-is as you say there is no problem with it. but in general you should use .equals() when it comes to compare strings in java.

Java issue using parseInt with a try catch block

I am working on an exercise, where I have to select a category(genre) of movie and based on my selection, the program will return a list of movies in that category from an ArrayList of objects.
My program works when typing out a category in string format. However I am trying to use a try catch block to also allow category selection by number.
My catch block is working, however my try block is not and returns nothing. Can someone help me determine what is wrong with my code? I am guessing there is something wrong with my parseInt assignment?
System.out.print("What category are you interested in?");
String catSel = sc.next();
try //Check category for Integer, otherwise catch
{
int numSel = Integer.parseInt(catSel);
if(numSel == 1)
{catSel = "animated" ;}
if(numSel == 2)
{catSel = "drama";}
if(numSel == 3)
{catSel = "horror";}
if(numSel == 4)
{catSel = "scifi";}
if(numSel == 5)
{catSel = "musical";}
if(numSel == 6)
{catSel = "comedy";}
else catSel = "";
//Check each movie for chosen category
for(int x = 0; x < list.size() - 1; x++)
{
if(catSel.equals(list.get(x).category))
System.out.println(list.get(x).movie);
}
}
catch (NumberFormatException e)
{
//Check each movie for chosen category
for(int x = 0; x < list.size() - 1; x++)
{
if(catSel.equals(list.get(x).category))
System.out.println(list.get(x).movie);
}
}
the way your if-clauses are structured, the else clause will be called whenever numSel is not 6, replacing catSel with the empty string.
You may want to add an else after each if block or replace all of them with a switch statement.
As #Dragondraikk suggested your if-else clauses are structured in a way which is not as per your expected result .
So either use in this way :
if(someCondition){
}
else if(someCondition){
}
...........................
do whatever you want to do
...........................
else{
}
Below is the way to use Switch Statement
switch(Integer.parseInt(catSel)){
case 1 :
do Something....
break;
case 2 :
do Something....
break;
case 3 :
do Something....
break;
case 4 :
do Something....
break;
case 5 :
do Something....
break;
case 6 :
do Something....
break;
default :
catSel="";
break;
}
Note : You can use try-catch block around this
Update
Advantage of Using Switch over If else
The problem with the if...else if... chain is readability , I have to look at every single if condition to understand what the program is doing. For example, you might have something like this:
if (a == 1) {
// stuff
} else if (a == 2) {
// stuff
} else if (a == 3) {
// stuff
} else if (b == 1) {
// stuff
} else if (b == 2) {
// stuff
}
(obviously, for a small number of statements like this, it's not so bad)
but I'd have no way of knowing that you changed condition variable half-way through without reading every single statement. However, because a switch limits you to a single condition variable only, I can see at a glance what's happening.
Another advantage is JumpTable
A switch is often compiled to a jump-table (one comparison to find out which code to run), or if that is not possible, the compiler may still reorder the comparisons, so as to perform a binary search among the values (log N comparisons). An if-else chain is a linear search .
Here is more about Switch Statement

Can you use conditional statements in switch-case in Android?

I can't seem to find a straight forward yes or no to this in my searching. In Android, is there a way to use a conditional statement in case-switch? For example, with age being an int value:
switch (age){
case (>79):
// Do this stuff
break;
case (>50):
// Do this other stuff
break;
etc, etc
I've tried several ways to code this (completely shooting in the dark) and come up with compiler errors, and I've also tried a nested IF statement, but it doesn't support break so the logic breaks down and it ends up also executing ELSE code lower in the nesting. I feel like switch-case is my best bet but I can't find an example of the correct syntax for what I'm trying to do! Any help would be appreciated. All the examples I find just use switch-case for a few things like if it is a 1 do this, if it's a 2 do that, but without making 100 case statements to check against age, I'm not sure how else to work this.
No. You cannot do this,
switch (age){
case (>79):
// Do this stuff
break;
case (>50):
// Do this other stuff
break;
}
You need an if and else,
if (age > 79) {
// do this stuff.
} else if (age > 50) {
// do this other stuff.
} // ...
It is not possible. Instead, Try this minimalist approach
age > 79 ? first_case_method()
: age > 50 ? second_case_method()
: age > 40 ? third_case_method()
: age > 30 ? fourth_case_method()
: age > 20 ? fifth_case_method()
: ...
: default_case_method();
You can't do this use if then statement.
if(age > 79)
{
//do stuff
}
else if(age > 50)
{
//do stuff
}
else
{
/do stuff
}
etc...
If you are using a loop you might want to look at What is the "continue" keyword and how does it work in Java?. This is not a good place to use switch.
if(age > 79)
{
//do stuff
continue; // STOP FLOW HERE AND CONTINUE THE LOOP
}
else if(age > 50)
{
//do stuff
continue; // STOP FLOW HERE AND CONTINUE THE LOOP
}
each case of switch is supposed to be an integer or String since JavaSE 7 and you are trying to feed a boolean value to it so its not possible .Read oracle doc to know about java switch in detail
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
You can't use conditional statements with switch.
But you CAN do it with if statements! If you have a loop you can use continue to stop any upcoming lines and start from the beginning of the innermost loop.
if(age>76){
// Code...
continue;
}else if(age>50){
// More Code...
continue;
}else{
// Even more code...
continue;
}
It can be done.
The code needs to be slightly altered.
public static void main(String[]arguments)
{
int x=1, age=55;
switch(x)
{
case 1: if((age>=60)&&(age<200))
System.out.println("Senior Citizen");
case 2: if((age>=18)&&(age<60))
System.out.println("Adult");
case 3: if((age>=12)&&(age<18))
System.out.println("Teenager");
break;
default :
System.out.println("Child");
break;
}
}

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

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.
I use this kind of pattern often. It's very compact:
Define a constant in your class:
private static final Set<Integer> VALUES = Set.of(12, 16, 19);
// Pre Java 9 use: VALUES = new HashSet<Integer>(Arrays.asList(12, 16, 19));
In your method:
if (VALUES.contains(x)) {
...
}
Set.of() returns a HashSet, which performs very well even for very large sets.
If performance is not important, you can code the gist of it into one line for less code footprint:
if (Set.of(12, 16, 19).contains(x))
but know that it will create a new Set every time it executes.
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;
}
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.
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.
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 :)
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;
}
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.
Here is another answer based on a comment above, but simpler:
List numbers= Arrays.asList(1,2,3,4,5);
if(numbers.contains(x)){
//
}

if loop processing efficiency

Which of the 2 is better from a processing or optimizing point of view?
I feel Option 1 is more readable, but I've been told Option 2 is more efficient. Is that so?
if (value != null) {
if (value.equalsIgnoreCase(ApplicationConstants.A)) {
} else if (value.equalsIgnoreCase(ApplicationConstants.B)) {
}
}
Option 2:
if ((value != null) && (value.equalsIgnoreCase(ApplicationConstants.A))) {
} else if ((value != null) && (value.equalsIgnoreCase(ApplicationConstants.B))) {
}
There's nothing here to care about performance wise, write your code so it's as readable as you can make it.
When performance testing later highlights areas that need to be optimized then and only then optimize only the places that need it.
To make it more readable you can invert your tests to get rid of the null check:
if (ApplicationConstants.A.equalsIgnoreCase(value)) {
} else if (ApplicationConstants.B.equalsIgnoreCase(value)) {
}
Option 1 is efficient since there is no redundant null check.
I'd expect the first to be slightly more efficient, because && is short-circuit, so it gives multiple conditional branches anyway. But if you want to be certain, time them.
I would go with option 1 as in option 2, more no of comparisons are made.
The first option is better as with one condition check you can decide.
so if value != null then only it will enter else it will not even enter the conditional block.
But in 2nd option it will check if condition , and if false also it wd check else condition (for value == null).

Categories