Writing Java long If/Else Loops in a shorter way - java

Hi guys i currently have a assignment which i just finished but their is one detail i dont love about it. Is there a way to shorten if else loops
Currently i have wrote
if (x >=300) {
set y = 1;
}
else if(x >=200) {
set y = 2;
}
else if (x >=150) {
set y = 3;
}
else if (x>=100) {
set y = 4;
}
else if (x >=50) {
set y = 5;
}
else if (x >=25) {
set y = 6;
}
Probably me just being pedantic, thanks in advance

You could shorten it to
y = x>=300 ? 1 : x>=200 ? 2 : x>=150 ? 3 : x>=100 ? 4 : x>=50 ? 5 : 6;
but while that may be more compact, it is also subjectively less readable. For additional informatione, see here.

This looks like a place where you could use the switch statement. However, the switch statement is designed to handle known values rather than inequalities. If you don't like the way the chain of if-else statements looks, you could do it all in an inline expression (Ternary Operator), but that makes it hard to read.
I'd say keep the code the way it is unless there's a good reason to change it. If you're only going to have one code statement after each statement, then you can eliminate the curly braces {} to make the code look a little cleaner:
if (x >= 300) set y = 1;
else if (x >= 200) set y = 2;
else if (x >= 150) set y = 3;
else if (x >= 100) set y = 4;
else if (x >= 50) set y = 5;
else if (x >= 25) set y = 6;

Related

How does one put a ternary operator inside the parenthesis of a for loop

I've recently learnt ternary operators and was practising them by making some old code i wrote a while back nicer. When trying to do this to a for loop in many different ways I can't seem to figure out how to do it. Ive tried:
for (hotbarFirst ? (x = 0; x < mc.player.inventoryContainer.getInventory().size(); x++) :
(x = mc.player.inventoryContainer.getInventory().size(); x > 0; x--)) {
and
for (hotbarFirst ? (x = 0) : (x = mc.player.inventoryContainer.getInventory().size());
hotbarFirst ? (x < mc.player.inventoryContainer.getInventory().size()) : (x > 0);
hotbarFirst ? (x++) : (x--)){
}
The first way gives me unexpected token errors and the second one gives me not a statement errors. It seems like I should be able to do this in some way or another, so am I just approaching it wrong or is there another way to do this without making two for loops.
(ignore the functions, they're for a game I made the mod in)
(Also incase you didnt notice I'm trying to iterate over a set of numbers two either back to front or front to back depedning on whether the bool is true or false)
original code:
public static int getItem(Item itemofChoice, boolean hotbarFirst) {
if (mc.player == null) return -1;
for (int x = 0; x < mc.player.inventoryContainer.getInventory().size(); x++) {
if ((x == 0 || x == 5 || x == 6 || x == 7 || x == 8)) continue;
ItemStack s = mc.player.inventoryContainer.getInventory().get(x);
if (s.isEmpty()) continue;
if (s.getItem().equals(itemofChoice)) return x;
}
return -1;
}
Im trying to make it iterate the opposite way if the bool param is true
Here is one way to do it:
int size = mc.player.inventoryContainer.getInventory().size();
for (int x = (hotbarFirst ? 0 : size-1); (hotbarFirst ? x < size : x >= 0) ; x += (hotbarFirst ? 1 : -1)) {
...
}

Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException: / by zero in part of the program where it should divide numbers

I tried searching stackoverflow for answer but i could not find it. i figured out when i remove part of the program that divides numbers:
if(znak == 0) {
Resenje = x + y;
}else if(znak == 1) {
Resenje = x - y;
}else if(znak == 2) {
Resenje = x/y;
} else if(znak == 3) {
Resenje = x*y;
}else {
System.out.println("Greska u programu");
}
that error does not appear. i think the problem maybe if number is float but it is stored in int... Thank you, if you need any additional information im here to provide it.. :)
PS code is messy because i made it long time ago.. sorry, i cant figure out how to properly format it, i posted it on pastebin, i hope you dont mind it.. :)
https://pastebin.com/sfG9JEbR link for code
while(vece = true) {
// System.out.println(Odabir1);
x = random.nextInt(Odabir1);
// System.out.println(x);
y = random.nextInt(Odabir1);
// System.out.println(y);
//if(x == (int)x) {
if(x-y >= 0 && x+y <= Odabir1 && x+y!=0 && x-y!=0 && x/y >= 0 && x/y == (int)x && x*y >= 0 && x*y <= Odabir1) {
System.out.println(x + " " + y);
break;
}
}
when i try adding && y == 0; i get same error in every possibility

double assignment in single instruction

This may sound crazy, but i'm curious to know if it is possible to use a single instruction to modify the values of two different variables.
For example, suppose i have this code (x and y are int variables):
if(x < 0) {
y -= x ;
x = 0;
}
If x is equal to -1, i would obtain the same result by doing the following :
if(x < 0) y -= x++;
Is there a way to generalise the previous result? I tried with the instruction :
if(x < 0) y -=x-=x;
But, while x at the end is equal to 0, y won't be modified. What i'm missing ?
EDIT
I thought (i was wrong probably) it was clear that my question was purely theoretical.
I know that this way of doing should be avoided. I was just curious :).
Try this:
if(x < 0) x = (y -= x) - y;
It's fine to try tricks like these for a challenge. However, Don't use this type of code in your actual code as it'll create confusion for others.

How would you compare multiple ints in 1 if statement without repeating it?

I have some coding in Java to calculate the movement in a virtual camera since the last time a variable was checked. More specifically, this code below:
float movementX, movementY, movementZ;
movementX = (int) (camX - sectorSize[1]);
movementY = (int) (camY - sectorSize[2]);
movementZ = (int) (camZ - sectorSize[3]);
/*
* If the variable is below 0
* then get the absolute value
* of the movement since the
* last camera position.
*/
if (movementX < 0) movementX *= -1;
if (movementY < 0) movementY *= -1;
if (movementZ < 0) movementZ *= -1;
if (movementX > 60 || movementY > 60 || movementZ > 60)
{
//Reset the sector size to allow for new points,
//don't store to save memory (may be changed later).
sectorSize[0] = 0;
}
If you need more of the code, let me know. The sectorSize variable stores 0-500 in its [0] value, the former camX in it's [1] value, the former camY in it's [2] value and lastly former camZ in its [3] value. The camX, camY, and camZ are handled by other code (not displayed). removed everything but the code-in-question to keep it tidy.
This code works as-is, but typing "if (a_int_value > an_other_value || etc)" each time is a bit tedious.
I would create a Movement class and encode the parameters for a "legal" movement within it.
Then you can test: movementX.isValid(). You can also keep a List or create another class to wrap the three axes and have a single isValid() method to test with.
You should consider storing sector sizes in something more descriptive than an array.
Finally, why are you casting your floats to int? What good can come from that? If you mean to strip off the decimal, there are much better ways to truncate, or floor/ceiling the value.
Put the moments into an int array.
Iterate over the array searching for all true conditions. If a true condition is encountered, mark the flag as true and break the loop. In the end, if no condition is true, your flag is false.
Something like this.
boolean ok = false;
for ( int v : momentArray ) {
if ( v > 60 ) {
ok = true;
break;
}
}
if ( ok ) {
// ok, do something...
}
Or
public static boolean checkForValues( int[] array, int min ) {
for ( int v : array ) {
if ( v > min ) {
return true;
}
}
return false;
}
// in another class...
if ( checkForValues( momentArray, 60 ) ) {
// ok, do something...
}
I'm assuming that all of conditions is the same. If they are different you can generalize the code too, but you will nedd to create a classe to store the conditions... It does not worth the work, so its preferable to code the conditions.
Another thing. You have just tree values. If you have lots of values (with the same condition) I think the iteration would be nice, but in your scenario, I think its better to code every condition because is easier to understand the code as Ghost said.
[]'s
Create a local class inside the method:
void myMethod ( )
{
class Movements
{
float movementX = (int) (camX - sectorSize[1]);
float movementY = (int) (camY - sectorSize[2]);
float movementZ = (int) (camZ - sectorSize[3]);
boolean check3Axes ( int commonValue )
{
return
movementX > commonValue
||
movementY > commonValue
||
movementZ > commonValue ;
}
void negate ( )
{
if (movementX > 0) movementX *= -1;
if (movementY > 0) movementY *= -1;
if (movementZ > 0) movementZ *= -1;
}
};
Movements m = new Movements( );
// This can be replaced with m.negate( )
if (m.movementX > 0) m.movementX *= -1;
if (m.movementY > 0) m.movementY *= -1;
if (m.movementZ > 0) m.movementZ *= -1;
if (m.check3Axes(60))
{
//do something..
}
if (m.check3Axes(120))
{
//do something else..
}
}
BTW, you may find that you can add more common methods to Movements class, such as negate().
At some point, though, it may be better to make Movement a regular class.
The inner-class looks like the best way to go. Too bad java doesn't provide anything less resource-intensive, but the ability to compare a bunch of variables with the same expression helps a lot!

Complex code/algorithm optimization (e.g. simplification) quandary

How can this code be simplified?
if (x == 0) x = 1;
else if (x == 1) x = 0;
else if (x == 2) x = 3;
else if (x == 3) x = 2;
If x is always between 0 and 3 then try this:
x ^= 1;
It toggles the least significant bit.
If x can be a value other than between 0 to 3 then you can first test for that:
if (x >= 0 && x <= 3) {
x ^= 1;
}
This is the simplest form possible:
if (x == 0) x = 1;
else if (x == 1) x = 0;
else if (x == 2) x = 3;
else if (x == 3) x = 2;
wait... that's exactly your code.
cryptic one liners are NOT simple.
You could use something like this:
int mymap[4] = {1,0,3,2};
and then in your code use this:
x = mymap[x];
To use your pseudocode notation, maybe:
if (x % 2 == 0) x = x + 1
else x = x - 1
e.g you are adding one if it is an even number, subtracting otherwise? In terms of optimization though, I don't see what is particularly slow or wrong with your original code.
if(x >= 0 && x <= 3)
if((x%2) != 0) //odd
x--;
else if((x%2) == 0) //even
x++;
Not that I think this is simpler, and it doesn't limit the case to 0..3, but:
x += (x % 2 == 0) ? 1 : -1;
x ^= x & ~3 == 0 ? 1 : 0;
Unfortunately my code was so simplified it failed to make the 30-character minimum...
A common approach for handling simple data like this is to use the switch statement.
The code would be more redable with a switch statement:
switch(x) {
case 0: x=1: break;
case 1: x=0: break;
case 2: x=3: break;
case 3: x=2; break;
}
However, it's just about code readbility, not algorithmics, nor optimization.
x^=1;
unless x can be lower than 0 or higher than 3, which the problem specification doesn't state.
if( 0 <= x && x <= 3 )
x ^= 1;
if ( x >>> 2 == 0 )
{ x ^= 1;
}
one liner:
x=(x==0)?1:((x==1)?0:(x==2)?3:(x==3)?2:x);
The best way to do this...
if(x % 2 == 0){
x = +x;
}else{
x = -x;
}
Probably using switch statements

Categories