? in Java

Hi all…

I have this question… I have seen many people type this

if (number1 == 100) ? break, number1++;

they say it is to reduce the number of RAM space used compared to this

if(number1 == 100){
break;
}else{
number1++;
}

I just dont understand why is that possible to write the first line and compile it. I tried to use the same line above to make the same effect however they give me an “illegal start of expression” error

Help pls?


public class Fun1{
	private int number1;
	
	public void run(){
		number1 = 10;
		System.out.println(number1);
		while(true){
			number1++;
			System.out.println(number1);
			try{
				Thread.sleep(50);
				if (number1 == 100) ? number1--,number1++;
			}catch(InterruptedException e){}
		}
	}
	public static void main(String []args){
		new Fun1().run();
	}
}

You need to write it like this:

(number1 == 100 ? break : number1++ )

Cheers,
Brett

Hey Brett

how do you put it in the code?

is it “if(number1 == 100 ? break : number1 ++);” ?

or is it just (number1 == 100 ? break : number1++ )

cause I cant seem to get it compiled

Sorry =/

Cheers!

I can’t think of this being compilable. the ? is part of a so called ternary operator and is IMHO only useful in assignments:


// assingn bar to foo as long as it is less than 100, else assign constant 100
int foo= bar<100?bar:100;

// which is equivalent to the followinr
int foo;
if(bar<100) foo=bar;
else bar=100;

I wouldn’t use the ternary construct in any other cases but the most simple ones, cause it leads to completely unreadable code. Also I doubt, that the ternary operator takes less space in byte code, but one never know…

you need to change it to this:


public class Fun1{
	private int number1;
	
	public void run(){
		number1 = 10;
		System.out.println(number1);
		while(true){
			number1++;
			System.out.println(number1);
			try{
				Thread.sleep(50);
				number1 == 100 ? number1-- : number1++;
			}catch(InterruptedException e){}
		}
	}
	public static void main(String []args){
		new Fun1().run();
	}
}

a colon separates the “if” and “else” portions of the ternary statement.

And I highly doubt the ternary statement compiles to anything different than what an equivalent if/else statement would.

The word break is reserved, so you cannot use it. You cannot have seen the code in question in a working program.

I like the ? stuff, it allows you to write complex stuff in very few lines:

Here are a few crazy lines I’ve done, lol;


P_X+=(float)Math.sin(P_ANGLE)*((((ACTIONS&A_FORWARD)==A_FORWARD))?(PLAYER_SPEED_FORWARD):(((ACTIONS&A_REVERSE)==A_REVERSE)?(-PLAYER_SPEED_REVERSE):0));
P_Y+=(float)Math.cos(P_ANGLE)*((((ACTIONS&A_FORWARD)==A_FORWARD))?(-PLAYER_SPEED_FORWARD):(((ACTIONS&A_REVERSE)==A_REVERSE)?(PLAYER_SPEED_REVERSE):0));
P_ANGLE = (float) ((P_ANGLE%(2*PI))+(((ACTIONS&A_TURNRIGHT)==A_TURNRIGHT)?PLAYER_SPEED_TURN:((ACTIONS&A_TURNLEFT)==A_TURNLEFT)?-PLAYER_SPEED_TURN:0));

I’ll give you a million bucks if you can sort that out :wink:

That’s not a good thing.

if ((ACTIONS & A_FORWARD) == A_FORWARD) // If move forward bit is set
{
    P_X += (float) Math.sin(P_ANGLE) * PLAYER_SPEED_FORWARD;
    P_Y -= (float) Math.cos(P_ANGLE) * PLAYER_SPEED_FORWARD;
}
else if ((ACTIONS & A_REVERSE) == A_REVERSE) // If reverse bit is set
{
    P_X -= (float) Math.sin(P_ANGLE) * PLAYER_SPEED_REVERSE;
    P_Y += (float) Math.cos(P_ANGLE) * PLAYER_SPEED_REVERSE;
}

if ((ACTIONS & A_TURNRIGHT) == A_TURNRIGHT) // If turn right bit is set
{
    P_ANGLE = (P_ANGLE % (2 * PI)) + PLAYER_SPEED_TURN;
}
else if ((ACTIONS & A_TURNLEFT) == A_TURNLEFT) // If turn left bit is set
{
    P_ANGLE = (P_ANGLE % (2 * PI)) - PLAYER_SPEED_TURN;
}

That code is MUCH clearer than your code, and also adds an option to let the user press both turn left and turn right at the same time by simply removing all “elses” from the code.
In case you thought your code was faster; it isn’t. In a microbenchmark, my code ran about 25% faster than your code on my computer, and provided identical output(*).
Your code, however, DOES generate a slightly smaller class file. :wink:

(* almost. Since I changed the order on some negations for clearer code, there’s some minor differences in the double -> float casting results)

Yea, I created it for the (this years) 4k competition. The ?-statements help make the code smaller.

Is it so? I never checked this myself, so there is really a dedicated bytecode in java for the ternary operator!? Well, one never stop learning…

No, there’s no special opcode, but since they don’t REALLY do the same thing, they compile slightly differently. Sometimes the ? is smaller, sometimes the if is smaller.

Here’s two examples:

    public static int foo(boolean b)
    {
        int dir = b?1:-1; 
        return dir;
    }

    public static int foo2(boolean b)
    {
        int dir;
        if (b)
            dir = 1;
        else 
            dir = -1;
        return dir;
    }

decompiles to:

public static int foo(boolean);
  Code:
   0:   iload_0
   1:   ifeq    8
   4:   iconst_1
   5:   goto    9
   8:   iconst_m1
   9:   istore_1
   10:  iload_1
   11:  ireturn

public static int foo2(boolean);
  Code:
   0:   iload_0
   1:   ifeq    9
   4:   iconst_1
   5:   istore_1
   6:   goto    11
   9:   iconst_m1
   10:  istore_1
   11:  iload_1
   12:  ireturn

BUT:

    public static int foo(boolean b)
    {
        return b ? 1 : -1;
    }

    public static int foo2(boolean b)
    {
        if (b) return 1;
        else return -1;
    }

decompiles to:

public static int foo(boolean);
  Code:
   0:   iload_0
   1:   ifeq    8
   4:   iconst_1
   5:   goto    9
   8:   iconst_m1
   9:   ireturn

public static int foo2(boolean);
  Code:
   0:   iload_0
   1:   ifeq    6
   4:   iconst_1
   5:   ireturn
   6:   iconst_m1
   7:   ireturn

So really, you need to test it in your app to see what’s smallest, or use a different compiler that’s smarter than javac. :wink:
It’s trivial to prove that all those four methods do the same thing, yet javac produces four different bytecodes for them.

(by the way, to decompile a class file, use “javap -c -classpath my.package.ClassName”)

Yes, there is almost no difference.

8 instructions vs. 9 instructions
and then 6 v 6 instructions.

[quote]Sometimes the ? is smaller, sometimes the if is smaller.
[/quote]
btw. the ternary operator is not larger than the if-operator. Count the instructions, don’t just look at the line no.

[quote=“appel,post:12,topic:28431”]
That’s not line numbers. It’s the actual numbers of bytes used for the bytecode.
goto, for example, takes up three bytes (opcode, offset high byte, offset low byte). Sure, it’s a single instruction, but it makes the byte code three bytes larger.

[quote=“Markus_Persson,post:13,topic:28431”]

I see.

Hmm… I understand the theory part of ? However… what I do not understand is that… i still cannot compile the codes

even this codes which is provided for me


public class Fun1{
	private int number1;
	
	public void run(){
		number1 = 10;
		System.out.println(number1);
		while(true){
			number1++;
			System.out.println(number1);
			try{
				Thread.sleep(50);
				number1 == 100 ? number1-- : number1++;
			}catch(InterruptedException e){}
		}
	}
	public static void main(String []args){
		new Fun1().run();
	}
}

It always gives me a “not a statement” error at the line “number1 == 100 ? number1-- : number1++;”

I really do not understand… I installed the latest JDK… and I still have this error… I really do not know what is going on…

=(

Replace the line you have with:

number1 = (number1 == 100 ? number1 - 1 : number1 + 1);

You can’t use the ? operator in isolation, it has to be part of a statement.

Cheers,
Brett

number1 == 100 ? number1-- : number1++;

This is most illogical. The number “100” is a integer, it cannot be true or false.
Also, this requires incrementing or decrementing number1 variable by one, and then assign value of number1 to number1, which is not necessery.

Better:

number1 += (number1 == 100) ? -1 : 1;

Thanks! I undestand ? in Java…

HOwever I would like to ask… is there any other special characters like ? used in java and what are they used for and how they are used?

^^

CHeers!

Oh God. Please let me never work on a project with you, and please let no one who writes code like this ever get near me :slight_smile:

You mean punctuation characters? Sure, there are plenty. Almost all of them you are well aware of (I sure hope you know what the semi colon is used for, for example)

Maybe one you’re not thinking of is in Java 5, the new “foreach” loop which uses a colon

for(Foo foo : myFoos) {
foo.doSomething();
}

it would have been nicer if that loop could have been

foreach(Foo foo in myFoos) {

}

as it is in C#, but introducing new keywords to a language is risky, and so Sun decided to not go that route. If nothing else, old programs that had “foreach” and “in” as variable names would have failed to compile.