Pete
Pete

Reputation: 17152

Compact Java syntax for conditional arguments?

What is the best (most compact) way to hand this situation: One or more arguments to a method call depends on some condition, while the rest of the arguments are identical?

For example-- you want to

DeathRay mynewWpn = new DeathRay(particle.proton, chassisColor.BLACK, oem.ACME)

if

enemy_composition == nature.ANTIMATTER

but

DeathRay mynewWpn = new DeathRay(particle.anti-proton, chassisColor.BLACK, oem.ACME)

if

enemy_composition == nature.MATTER

Obviously you can if-else but it looks unnecessarily long when there are a lot of arguments or more than one conditional argument. I have also done this creating an argument with an if-else beforehand and then calling the method. Again, that seems kind of clunky. Is there some sort of inline syntax similar to an Excel if-statement?

Upvotes: 3

Views: 2395

Answers (5)

Hendra Jaya
Hendra Jaya

Reputation: 1628

How about redesigning some class?

In Nature class, compose some method like getDestroyer().

abstract class Enemy{
   abstract Weapon getDestroyer();
}

Then in concrete class like :

class MatterEnemy extends Enemy{
   Weapon getDestroyer(){return new DeathRay(antiproton, blabla);}
}

You implement such method. So your main class will be :

public static void main(String... args){
  Enemy enemy = new MatterEnemy();
  Weapon weapon = enemy.getDestroyer();
}

This way you can avoid conditional 'ifs'. Instead, the Enemy itself 'tells' you what weapon should be used to destroy them.

Upvotes: 2

erickson
erickson

Reputation: 269847

You can do

new DeathRay(enemy_composition == nature.ANTIMATTER ? particle.proton : particle.anti-proton, chassisColor.BLACK, oem.ACME)

… but I think we can all agree that's hideous. It also assumes that there are only two kinds of particle.

Here are some better alternatives.

switch:

particle type;
switch (enemy_composition) { /* Assuming "nature" is an enum. */
  case ANTIMATTER : 
    type = particle.proton;
    break;
  case MATTER : 
    type = particle.antiproton;
    break;
}
DeathRay mynewWpn = new DeathRay(type, chassisColor.BLACK, oem.ACME);

enum method:

Add a method to your enum, Nature.

public enum Nature
{

  MATTER
  {
    public Particle getCounterWeapon()
    {
      return Particle.ANTIPROTON;
    }
  },
  ANTIMATTER
  {
    public Particle getCounterWeapon()
    {
      return Particle.PROTON;
    }
  };

  public abstract Particle getCounterWeapon();

}

Then use it.

DeathRay mynewWpn = new DeathRay(enemy_composition.getCounterWeapon(), chassisColor.BLACK, oem.ACME);

Map:

particle type = counterWeapons.get(enemy_composition);
DeathRay mynewWpn = new DeathRay(type, chassisColor.BLACK, oem.ACME);

Upvotes: 5

Tom
Tom

Reputation: 45154

You can use a MAP and the command pattern to avoid the if-else.

For eexample

Map<EnemyCompositionEnum,DeathRay> weapons = new HashMap<EnemyCompositionEnum,DeathRay>();

weapons.put(EnemyCompositionEnum.ANTIMATTER, new DeathRay(particle.proton,BLACK,oem.ACME));
weapons.put(EnemyCompositionEnum.MATTER, new DeathRay(particle.anti-proton,BLACK,oem.ACME));

And then use it

DeathRay weapon = weapons.get(enemy.composition);

update

Ok , I just realized whats an Excel ternary operator by reading other answers.

Upvotes: 1

Walter Rumsby
Walter Rumsby

Reputation: 7535

If enemy_composition can only be nature.MATTER or nature.ANTIMATTER then you could use a ternery operator:

DeathRay mynewWpn = new DeathRay(enemy_composition == nature.MATTER ? particle.anti-proton : particle.proton, chassisColor.BLACK, oem.ACME)

Upvotes: 2

Adam Rosenfield
Adam Rosenfield

Reputation: 400592

Yes, it's called the ternary operator ?:

DeathRay mynewWpn = new DeathRay(
    enemy_composition == nature.ANTIMATTER ? particle.proton : particle.anti_proton,
    chassisColor.BLACK, oem.ACME);

The syntax is condition ? value_if_true : value_if_false, and it has the lowest operator precedence, although parentheses are often added to avoid confusion.

Upvotes: 2

Related Questions