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.
精彩评论