Reputation: 17152
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
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
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
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);
Ok , I just realized whats an Excel ternary operator by reading other answers.
Upvotes: 1
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
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