3

I've just started learning java and have a really basic question. I have a label that I want to change colors when a random integer between 1 and 18 lands on a particular number. These numbers are not odd or even, so I can't use that.

Right now I have this:

    if (Random == 1 || Random == 2 || Random == 5 || Random == 7 || Random == 12 || Random == 14 || Random == 16 || Random == 18)  
        label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
    else if (Random == 3 || Random == 4 || Random == 6 || Random == 8 || || Random == 9 | Random == 10 || Random == 11 || Random == 13 || Random == 15 || Random == 17)
        label_wheelNumber.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));

I know it looks silly, and I feel like an idiot doing it this way. What do you recommend? I haven't taken a class so any explanations are extremely useful. Thanks

9 Answers9

10

Here is an example of a switch: Note the break; when using a switch, the case will fall through. Essentially, case 1: will fall through to the next code block. For example in my code, in case 5: if the break; was not there, it would fall through to the next code block and end up with the second code block containing SWT.COLOR_GREEN being called as well.

switch(Random)
{
    case 1:
    case 2:
    case 5:
        label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
        break;
    case 9:
    case 10:
        label_wheelNumber.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
        break;
}
Patrick J Abare II
  • 1,129
  • 1
  • 10
  • 31
9

You may use a switch:

switch(Random) {
    case 1: case 2: case 5: case 7: case 12: case 14: case 16: case 18:
        //something...
        break;
    case 3: case 4: case 6: case 8: case 9: case 10: case 11: case 13: case 15: case 17:
        //something...
        break;
    default: 
        //just in case none of the over values was selected
}

If the values may vary fast or you want to allow more values, you can store them in an array or similar:

static final int[] FOREGROUND_BLUE = {1, 2, 5, 7, 12, 14, 16, 18};
static final int[] FOREGROUND_GREEN = {3, 4, 6, 8, 9, 10, 11, 13, 15, 17};

And then perform a search to seek if the value belongs to the specified array:

//using binary search since the data in the array is already sorted
int found = Arrays.binarySearch(FOREGROUND_BLUE, Random);
if (found >= 0) {
    //something...
}
found = Arrays.binarySearch(FOREGROUND_GREEN, Random);
if (found >= 0) {
    //something...
} else {
    //...
}

In case you can even have more options, probably you want to use a cache-like approach and store the data in a Map<Integer, Color>:

static final Map<Integer, Color> colorMap;
static {
    Map<Integer, Color> colorMapData = new HashMap<Integer, Color>();
    Color blue = SWTResourceManager.getColor(SWT.COLOR_BLUE);
    Color green = SWTResourceManager.getColor(SWT.COLOR_GREEN);
    colorMapData.put(1, blue);
    colorMapData.put(2, blue);
    colorMapData.put(3, green);
    colorMapData.put(4, green);
    colorMapData.put(5, blue);
    //...
    //this makes colorMap truly constant and its values cannot be modified
    colorMap = Collections.unmodifiableMap(colorMapData);
}

And then you just call the value from map:

Color = colorMap.get(Random);
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
1

Use a Switch statement:

public class SwitchDemo {
   public static void main(String[] args) {

    int month = 8;
    String monthString;
    switch (month) {
        case 1:  monthString = "January";
                 break;
        case 2:  monthString = "February";
                 break;
        case 3:  monthString = "March";
                 break;
        case 4:  monthString = "April";
                 break;
        case 5:  monthString = "May";
                 break;
        case 6:  monthString = "June";
                 break;
        case 7:  monthString = "July";
                 break;
        case 8:  monthString = "August";
                 break;
        case 9:  monthString = "September";
                 break;
        case 10: monthString = "October";
                 break;
        case 11: monthString = "November";
                 break;
        case 12: monthString = "December";
                 break;
        default: monthString = "Invalid month";
                 break;
    }
    System.out.println(monthString);
}
}

Taken from: Oracle's Java Tutorial.

abalos
  • 1,301
  • 7
  • 12
1

There may be better options depending on where Random is coming from and in what context this is happening, but one option you have to do basically the same thing with a different syntax is:

switch(Random) {
    case 1:
    case 2:
    case 5:
    case 7:
    case 12:
    case 14:
    case 16:
    case 18:
        label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
        break;
    case 3:
    case 4:
    case 6:
    case 8:
    case 9:
    case 10:
    case 11:
    case 13:
    case 15:
    case 17:
        label_wheelNumber.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
        break;
}

That is only marginally better than what you have but I think it is at least a little easier to look at.

Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
1

If you use a map you can turn this into a one-liner (eliminate the if/switch completely).

HashMap<Integer, Color> mp = new HashMap<Integer, Color>();

mp.put(1, SWT.COLOR_BLUE);
mp.put(2, SWT.COLOR_BLUE);
...
mp.put(18, SWT.COLOR_BLUE);

mp.put(3, SWT.COLOR_GREEN);
mp.put(4, SWT.COLOR_GREEN);
...
mp.put(17, SWT.COLOR_GREEN);


...

label_number.setForeground(SWTResourceManager.getColor(mp.get(Random)));

Also, name your Random variable differently as it clashes with a class name from the Java API.

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
1

Use a lookup list:

int[] ALLOW_BLUE = {1,2,5,7,12,14,16,18};
int[] ALLOW_GREEN = {3,4,6,8,9,10,11,13,15,17};

     if(Arrays.asList(ALLOW_BLUE).contains(random){
        label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
     }
else if(Arrays.asList(ALLOW_GREEN).contains(random){
        label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
     }
Narmer
  • 1,414
  • 7
  • 16
  • Since the values in the array are sorted, you may take advantage of this and use binary search provided by Java in `Arrays#binarySearch` so you won't have the overhead of converting the array into a List and perform a linear search. – Luiggi Mendoza Jul 01 '14 at 15:38
  • Also, the variable could be a list it self, there's no need to create a new one each time the if is evaluated. – OscarRyz Jul 01 '14 at 15:54
  • You are both right, I could have used a [double brace initialization](http://stackoverflow.com/q/924285/3735079) and a binary search on the `List`. But here it would save only some milliseconds... Indeed with those devices it's the best solution. – Narmer Jul 01 '14 at 16:01
1

Switch case will do but another way you can do is

int[] blueArray ={1,2,5,7,12,14,16,18};

if(Utils.arrayContain(blueArray,Random)){//your  util method
       label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
}elseif(){
}

Take your possible values in an array and check Random is there in that value or not.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
0

A more elegant way would be to place each group of numbers in an ArrayList and then check if the Random number is contained in the array with the contains() method:

if(Arrays.asList(new Integer[]{1, 2, 5, 7, 12, 14, 16, 18}).contains(Random )) {
    label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
} else if (Arrays.asList(new Integer[]{3, 4, 6, 8, 9, 10, 11, 13, 15, 17}).contains(Random)) {
    label_wheelNumber.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
}

For performance concerns you can also declare and store these arrays separately instead of creating them on the fly everytime you want to make the comparison.

Roberto Linares
  • 2,215
  • 3
  • 23
  • 35
0

For situations where you can't use a switch but you still have some complicated condition to evaluate you can use an "explanatory variable"

// before
if ( a && b || c != d && e > f && g < h && h == 1 ) { 
   doSomething();
} else if ( i && j || etc ) {
   doSomethingElse();
}

//after with a variable
boolean shouldDoSomething = a && b || c != d && e > f && g < h && h == 1;
if ( shuoldDoSomething ) { 
   doSomething();
} else if ( i && j || etc ) {
   doSomethingElse();
}

Or create a method that evaluates the condition:

// after with a method 
if ( shouldDoSomething(a,b,c,d,e,f,g,h) ) { 
   doSomething();
} else if ( shouldDoSomethingElse(i, j, etc ))  {
   doSomethingElse();
}
...
private boolean shouldDoSomething( boolean a,boolean b,int c,int d,int e,int f,int g,int h) {
    return a && b || c != d && e > f && g < h && h == 1;
}
private boolean shouldSoSomethingElse(boolean i, boolean j, boolean etc ) {
    return i && j || etc;
}

The objective is to simplify your code allowing you to understand it better and making it easier to modify a less error prone. If using a variable or creating a method is more confusing then continue with the simple evaluation. You can also combine the three:

//
boolean shouldDoX = a || b; 
if  ( shouldDoX || e != d && inRange(f, g, h ) ) {
  doSomething();
} 

Again the objective is to make it easier to maintain.

In this example the variables are a, b, c but in real code you should use a short meaningful variable name

if ( inRange(random) ) { 
    label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
} else if ( outOfRange(random)) { 
    label_wheelNumber.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
}  

...
private boolean inRange(int random ) {
   // use switch or simple return random == 1 || random == 2 etc. 
}

Also, final notes on style: do always use brace on your if's even if they are one line and keep the opening brace in the same line. In Java, variables start with lowercase and are written in camelStyle ( no underscores ). These are just style conventions and will help you to create good habits. Each language has its own conventions, learn them and use them.

OscarRyz
  • 196,001
  • 113
  • 385
  • 569