开发者

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

Ob开发者_JS百科viously 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?


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);


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.


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)


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜