2

I am writing a little program which converts all kind of units into other ones. I have the gui and the program working fine but I feel like there is a better way to do it since I have a lot of if statements and switches. For example if the user wants to convert from one currency to another, he choses both currencies with a dropbox. Lets call them fromCurrency and toCurrency. solution will be the result at the end and amount is the amount of money which should be converted. The code for the calculation looks like this:

double convertIt(String fromCurrency, String toCurrency, double amount, double solution)

 switch (fromCurrency) {

        case "Euro":
            if(toCurrency == "US-Dollar"){
                solution = amount*(1.2407);
            }
            if(toCurrency == "Canadian Dollar"){
                solution = amount*(1.5492);
            }
            // ...     
            // ... checking all possible currencies in which you could convert, then next case

I know this might be pretty basic for most of you but I am really working alot on learning java for a while now and want to understand how to solve problems efficient and elegant. Because of that I would apprecciate any kind of hints on how to solve this problem more efficient since it doesnt feel that way, or at least it doesnt feel elegant. For example 10 currencies would mean 10 switches with 9 if statements each and there will probably be more

Olivier Grégoire
  • 33,839
  • 23
  • 96
  • 137
jfordummies
  • 167
  • 2
  • 9

3 Answers3

3

Use a table-like structure.

Use a structure like Guava's Table. These allow you to map two values to a third, just like a double-entry table.

Table<String,String,Double> currencyChanges = HashBasedTable.create();
currencyChanges.put("Euro", "US-Dollar", 1.2407);
currencyChanges.put("Euro", "Canadian Dollar", 1.5492);
...

// Later

Double currencyChange = currencyChanges.get(from, to);
solution = amout * currencyChange;

Note: you should use BigDecimal for monetary purposes, not doubles.

Olivier Grégoire
  • 33,839
  • 23
  • 96
  • 137
  • There's no need to bring in a 3rd party library for something as simple as this. Just use a `Map`. – ack Feb 05 '18 at 16:12
  • @AlexQuilliam That answer is already provided by user7294900. I don't see why I should copy that answer to mine as the ideas are different enough to merit two different answers. – Olivier Grégoire Feb 05 '18 at 16:15
  • This seems to be a pretty good solution, I will try this out for sure. Thanks alot for the answer! – jfordummies Feb 05 '18 at 16:28
  • I will probably try the way with the map first, but I still have a question on why using BigDecimal is better? As far as I see the only difference is that BigDecimal can handle bigger numbers, is that the only reason? I would assume that the range of doubles is way more than enough. Using doubles and rounding it up to 2 places worked fine til now – jfordummies Feb 05 '18 at 16:37
  • @jfordummies I think [this question and its answers](https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency) will answer all your questions on that topic. – Olivier Grégoire Feb 05 '18 at 16:41
  • @OlivierGrégoire You were right, it did :-) Thanks! – jfordummies Feb 05 '18 at 16:44
2

Consider selecting a base currency (e.g. the Euro) to base all of your calculations on. Create an enum based on each currency's value compared to the Euro:

public enum Currency
{
    EUR(1.00),
    USD(1.2407),
    CAD(1.5492),
    // Any other currencies you wish to support
}

Then, just take the amount you get and convert it to Euros, then to the final currency:

amount *= Currency.USD.ordinal() / Currency.CAD.ordinal();

Where USD is the original currency and CAD is the final currency.

0

You should save once in map with key fromCurrency + toCurrency and its value is the currency rate

 Map<String, Double> currenciesRate = ...

And in your method just get the value

 Double rate = currenciesRate.get(fromCurrency + toCurrency);
  solution = amount*rate;

You will be better off using your own object as a key for the map.

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • But how would I do this with only one String and one Double as values in the map? I think I would need Map, since I need two currencies to do the calculation or am I misunderstanding something? – jfordummies Feb 05 '18 at 19:50
  • You would concatenate the two currency strings together to form one unique key. For example, the exchange rate from `"Dollar"` to `"Euro"` would be represented with the key `"DollarEuro"`. – ack Feb 05 '18 at 20:00