Learn the most important control and control categories that every architect and developer should include in their projects.

Playing around again with adding Units to a Java program. Trying another approach, I ended up with a monolithic method, which the code is so ugly I'll post it lower down, and just describe here the simple idea of what it does.

It's basically a huge__nested__ **if-else** statement, which determines which units we currently have and what units we want to convert to, and then calling the appropriate conversion.

For my test example I have two Measurement types:**Temperature** and **Length**.

**Temperature** measurements have 3 units to choose from: **Fahrenheit, Celsius, and Kelvin**.

**Length** measurements have 3 units to choose from: **Inches, Feet, Miles**.

So basically I first determine if this is a**Temperature** measurement or a **Length** measurement.

For a**Temperature** measurement the possibilities are:

Fahrenheit → Fahrenheit

Fahrenheit → Celsius

Fahrenheit → Kelvin

Celsius → Fahrenheit

Celsius → Celsius

Celsius → Kelvin

Kelvin → Fahrenheit

Kelvin → Celsius

Kelvin → Kelvin

(Note how this looks like an Array.)

For a**Length** measurement the possibilities are:

Inches → Inches

Inches → Feet

Inches → Miles

Feet → Inches

Feet → Feet

Feet → Miles

Miles → Inches

Miles → Feet

Miles → Miles

As you can imagine this leads to a very ugly nested if-else statement which while in theory it works, I'm looking for a nicer alternative.

that looks like this:**Polymorphism** and **Strategy Pattern**, but I realized that was just spreading out the **if-else** statements so they were all over the place, rather than reducing them or eliminating them.

Next (and current) idea is to create a HashMap, with an array of**keys** for the units (from *this unit* to *that unit*), and the **value** will be the appropriate conversion method (I'm expecting something implementing the *callable* interface).

My units are**enums**: Temperature={FAHRENHEIT, CELSIUS, KELVIN}, Length={INCHES, FEET, MILES}

Now I'm wondering how to implement this Map of Array → Values. I can think of two possibilities:

1. Somehow flatten my 2-D Array of enum Keys to a 1-D array of Keys, and then use HashMap.

OR

2. Create a nested tree of HashMaps.

It's basically a huge

For my test example I have two Measurement types:

So basically I first determine if this is a

For a

Fahrenheit → Fahrenheit

Fahrenheit → Celsius

Fahrenheit → Kelvin

Celsius → Fahrenheit

Celsius → Celsius

Celsius → Kelvin

Kelvin → Fahrenheit

Kelvin → Celsius

Kelvin → Kelvin

(Note how this looks like an Array.)

```
Fahrenheit Celsius Kelvin
+----------+-------+-------+
Fahrenheit| | | |
+----------+-------+-------+
Celsius | | | |
+----------+-------+-------+
Kelvin | | | |
+----------+-------+-------+
```

For a

Inches → Inches

Inches → Feet

Inches → Miles

Feet → Inches

Feet → Feet

Feet → Miles

Miles → Inches

Miles → Feet

Miles → Miles

As you can imagine this leads to a very ugly nested if-else statement which while in theory it works, I'm looking for a nicer alternative.

that looks like this:

```
public double getValueAs(T targetUnits) {
// TEMPERATURE MEASUREMENT *******************************************
if (this.measurementUnits.getClass() == TemperatureUnits.class) {
if (targetUnits == TemperatureUnits.FAHRENHEIT) {
if (this.measurementUnits == TemperatureUnits.FAHRENHEIT) {
return this.value;
}
else if (this.measurementUnits == TemperatureUnits.CELSIUS) {
return convertCelsiusToFahrenheit(this.value);
}
else if (this.measurementUnits == TemperatureUnits.KELVIN) {
return convertKelvinToFahrenheit(this.value);
}
else {
//can not convert
}
}
else if (targetUnits == TemperatureUnits.CELSIUS) {
if (this.measurementUnits == TemperatureUnits.FAHRENHEIT) {
return convertFahrenheitToCelsius(this.value);
}
else if (this.measurementUnits == TemperatureUnits.CELSIUS) {
return this.value;
}
else if (this.measurementUnits == TemperatureUnits.KELVIN) {
return convertKelvinToCelsius(this.value);
}
else {
//can not convert
}
}
else if (targetUnits == TemperatureUnits.KELVIN) {
if (this.measurementUnits == TemperatureUnits.FAHRENHEIT) {
return convertFahrenheitToKelvin(this.value);
}
else if (this.measurementUnits == TemperatureUnits.CELSIUS) {
return convertCelsiusToKelvin(this.value);
}
else if (this.measurementUnits == TemperatureUnits.KELVIN) {
return value;
}
else {
//can not convert
}
}
else {
//can not convert
}
}
// LENGTH MEASUREMENT *******************************************
else if (this.unitType == LengthUnits.class) {
if (targetUnits == LengthUnits.INCHES) {
if (this.measurementUnits == LengthUnits.INCHES) {
return this.value;
}
else if (this.measurementUnits == LengthUnits.FEET) {
return convertFeetToInches(this.value);
}
else if (this.measurementUnits == LengthUnits.MILES) {
return convertMilesToInches(this.value);
}
else {
//can not convert
}
}
else if (targetUnits == LengthUnits.FEET) {
if (this.measurementUnits == LengthUnits.INCHES) {
return convertInchesToFeet(this.value);
}
else if (this.measurementUnits == LengthUnits.FEET) {
return value;
}
else if (this.measurementUnits == LengthUnits.MILES) {
return convertMilesToFeet(this.value);
}
else {
//can not convert
}
}
else if (targetUnits == LengthUnits.MILES) {
if (this.measurementUnits == LengthUnits.INCHES) {
return convertInchesToMiles(this.value);
}
else if (this.measurementUnits == LengthUnits.FEET) {
return convertFeetToMiles(this.value);
}
else if (this.measurementUnits == LengthUnits.MILES) {
return value;
}
else {
//can not convert
}
}
else {
//can not convert
}
}
return 0;
}
```

My first attempt was to try Next (and current) idea is to create a HashMap, with an array of

My units are

Now I'm wondering how to implement this Map of Array → Values. I can think of two possibilities:

1. Somehow flatten my 2-D Array of enum Keys to a 1-D array of Keys, and then use HashMap.

OR

2. Create a nested tree of HashMaps.

(Oh yes, and also "Create an Interface so the implementation details can change later on if I come up with a better way.")

Any ideas or suggestions? Preference for idea #1 or #2? Perhaps a #3 idea I haven't thought of yet?
Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get this solution by purchasing an Individual license!
Start your 7-day free trial.

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trialMy next thought was my

Is there a way to extract some of this conversion code into it's own class without using a cast? I tried making a

```
public double getValueAs(T targetUnits) {
if (this.measurementUnits.getClass() == TemperatureUnits.class) {
return TemperatureConverter.convert((TemperatureUnits) this.measurementUnits, (TemperatureUnits) targetUnits, this.value);
}
```

(plus I haven't actually tested the Is there a nicer way to code this?

Oh yes that is a good idea. I has the same idea and noticed JScience did the same thing: convert to a base unit, then from there convert to targetUnit.

Is there a way to extract some of this conversion code into it's own class without using a cast?

I've already given you a solution for this. Did you not read these posts that we took the time to provide to you?

Great minds think alike :)

Doug

P.S. As for the follow-up question, you could always just go with

public double getTemperatureValueAs(Temp

and you should find no casts required now.

In general I think you're struggling between trying to make everything super general and then later on trying to impose type safety. Easier to just start type safe if you can.

```
public class Measurement<T extends Units> {
private Class<T> unitType;
private T measurementUnits;
private double value;
public Measurement(T u, double v) {
this.value = v;
this.measurementUnits = u;
this.unitType = u.getClass(); // CAN'T DO THIS
T[] x = u.values(); // CAN'T DO THIS
}
```

So I'm switching back to my original idea of generating massive amounts of nearly identical code using a Code Template and a simple code generating program which replaces "MeasurementType" with "Temperature" or "Length" or whatever...
Java

From novice to tech pro — start learning today.

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get this solution by purchasing an Individual license!
Start your 7-day free trial.

The problem is that your basic approach is quadratic in the number of units. You have 3 possible inputs and 3 possible outputs, so there are 9 cells (3x3) in your matrix. But if you expand this to 6 units, you get 36 cells in your matrix, each of which needs the correct code (the correct Callable). It's the sort of design that leads to problems - because it's easy to get it right for 33 of those 36 and wrong for the last 3 and then that's very hard to find. (Why does converting to Farenheit work from Kelvin, but not from Celsius? etc.)

What I'd propose instead is reducing the complexity to a linear relationship with your number of units. You can do that by mapping from an arbitrary input unit to one standard unit and then from that standard unit back to an arbitrary unit. That way if you have 6 units, there are 6 mappings to the standard and then 6 back. Which is linear rather than quadratic, so much easier to test and get right.

Let me make that a bit more concrete with some code...which I hope you can see is simpler, because each method is pretty short and easy to understand. Also if you wish to add a new set of units, the places to put the new conversion are pretty obvious.

Any good?

Doug

Open in new window