这是我的第一个程序。我想创建一个转换货币并向用户提供有关如何最好地花钱的建议。我需要一些进步

This is my first program. I wanted to create a converts currencies and gives advices to user on how best to spend money. I need some advances

package firstproject;
import java.util.Scanner;
public class Currency{
    public static void main(String[] args) {

        int rubles = 100;
        double rateUSD = 1.35;
        double rateEUR = 1.20;
        double rateGBP = 1.02;
        double rateJPY = 153.29;

        // Interface
        System.out.println("Welcome to the Currency Converter Program \n");
        System.out.println("Используйте одну из перечисленных валют для конвертации: \n 1 - Rubles \n 2 - US dollars \n 3 - Euros \n 4 - British Pounds \n 5 - Japanese Yen \n");
        System.out.println("Please choose the input currency");
        Scanner in = new Scanner(System.in);
        int choice = in.nextInt();
        String inType;
        switch(choice) {
            case 1 -> inType = "Rubles >> " + rubles;
            case 2 -> inType = "US Dollars >> " + rateUSD;
            case 3 -> inType = "Euros >> " + rateEUR;
            case 4 -> inType = "British Pounds >> " + rateGBP;
            case 5 -> inType = "Japanese Yen >> " + rateJPY;
            default -> {
                System.out.println("Какая печаль, я пока не знаю такой валюты.\nПожалуйста, перезапустите программу и выберите валюту из списка :)");
                return;
            }
        }  System.out.println("Please choose the output currency");
        Scanner scanner = new Scanner(System.in);

        System.out.println("Сколько денег у вас осталось до зарплаты?");
        double moneyBeforeSalary = scanner.nextDouble();

        System.out.println("Сколько дней до зарплаты?");
        int daysBeforeSalary = scanner.nextInt();

        System.out.println("Введите команду. Доступные команды: convert и advice.");
        String command = scanner.next();

        if (command.equals("convert")) {

                System.out.println("В какую валюту хотите конвертировать рубли? Доступные варианты: USD, EUR, JPY, GBP.");

                String currency = scanner.next(); // считываю значения с помощью scanner

                if (currency.equals("RUB")) {
                    System.out.println("Ваши сбережения в рублях: " + moneyBeforeSalary / rubles);

                }
                switch (currency) {
                    case "RUS" -> System.out.println("Ваши сбережения в рублях:" + rubles );
                    case "USD" -> System.out.println("Ваши сбережения в долларах: " + moneyBeforeSalary / rateUSD);
                    case "EUR" -> System.out.println("Ваши сбережения в евро: " + moneyBeforeSalary / rateEUR);
                    case "GBP" -> System.out.println("Ваши сбережения в долларах: " + moneyBeforeSalary / rateGBP);
                    case "JPY" -> System.out.println("Ваши сбережения в иенах: " + moneyBeforeSalary / rateJPY);
                    default -> System.out.println("Валюта не поддерживается.");
                }

            } else if (command.equals("advice")) {
            if (moneyBeforeSalary < 3000) {
                System.out.println("Сегодня лучше поесть дома. Экономьте, и вы дотянете до зарплаты!");
            } else if (moneyBeforeSalary < 10000) {
                if (daysBeforeSalary < 10) {
                    System.out.println("Окей, пора в Макдак!");
                } else {
                    System.out.println("Сегодня лучше поесть дома. Экономьте, и вы дотянете до зарплаты!");
                }
            } else if (moneyBeforeSalary < 30000) {
                if (daysBeforeSalary < 10) {
                    System.out.println("Неплохо! Прикупите долларов и зайдите поужинать в классное место. :)");
                } else {
                    System.out.println("Окей, пора в Макдак!");
                }
            } else {
                if (daysBeforeSalary < 10) {
                    System.out.println("Отлично! Заказывайте крабов!");
                } else {
                    System.out.println("Неплохо! Прикупите долларов и зайдите поужинать в классное место. :)");
                }
            }
        } else {
            System.out.println("Извините, такой команды пока нет.");
        }
    }
}

我不确定switch(choice),我认为这里是多余的。我缺少正确转换货币的代码。我找到了货币转换器的示例,但出于某种原因,他们将其变量称为 char 类型。我是初学者,一直不明白为什么要给这样的变量赋一个货币值。我发现了类似的东西:char us_dollar_sym = 36;但是我没看懂这些变量的逻辑是什么。

毕竟,char 可以存储一个符号,而不是数字...或者不是?

一些改进代码的建议

  • 将程序分解成更小的部分
  • 使用转换方法
  • 对某些 if/else 分支使用方法
  • 对公共信息使用常量

这将使它更易于阅读和维护

  • 使用BigDecimal代替double
  • 为你的除法选择一种舍入模式(在我使用“半偶数”的代码中)

这将避免意外的精度损失。

正如 Turing85 在评论中提到的,浮点数(即双精度)不适合表示金钱。这是因为浮点数可能无法准确表示值(您可能会失去精度)。查看更多 here.

例如

import java.io.PrintStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Scanner;


public class Test {

    private final static Scanner IN = new Scanner(System.in);
    private final static PrintStream OUT = System.out;
    
    private static final BigDecimal RUBLES = BigDecimal.valueOf(100);
    private static final BigDecimal RATE_USD = BigDecimal.valueOf(1.35);
    private static final BigDecimal RATE_EUR = BigDecimal.valueOf(1.20);
    private static final BigDecimal RATE_GBP = BigDecimal.valueOf(1.02);
    private static final BigDecimal RATE_JPY = BigDecimal.valueOf(153.29);
    private static final RoundingMode ROUNDING_MODE = RoundingMode.HALF_EVEN;
    
    public static void main(String[] args) {
        // Interface
        OUT.println("Welcome to the Currency Converter Program \n");
        OUT.println("Используйте одну из перечисленных валют для конвертации: \n 1 - Rubles \n 2 - US dollars \n 3 - Euros \n 4 - British Pounds \n 5 - Japanese Yen \n");
        OUT.println("Please choose the input currency");
        choose();
        OUT.println("Сколько денег у вас осталось до зарплаты?");
        BigDecimal moneyBeforeSalary = BigDecimal.valueOf(IN.nextDouble());
        OUT.println("Введите команду. Доступные команды: convert и advice.");
        String command = IN.next();
        if (command.equals("convert")) {
            convert(moneyBeforeSalary);
        } else if (command.equals("advice")) {
            OUT.println("Сколько дней до зарплаты?");
            BigDecimal daysBeforeSalary = BigDecimal.valueOf(IN.nextInt());
            advice(moneyBeforeSalary, daysBeforeSalary);
        } else {
            OUT.println("Извините, такой команды пока нет.");
        }
    }

    private static void advice(BigDecimal moneyBeforeSalary, BigDecimal daysBeforeSalary) {
        if (moneyBeforeSalary.compareTo(BigDecimal.valueOf(3000)) < 0) {
            OUT.println("Сегодня лучше поесть дома. Экономьте, и вы дотянете до зарплаты!");
        } else if (moneyBeforeSalary.compareTo(BigDecimal.valueOf(10000)) < 0) {
            if (daysBeforeSalary.compareTo(BigDecimal.valueOf(10)) < 0) {
                OUT.println("Окей, пора в Макдак!");
            } else {
                OUT.println("Сегодня лучше поесть дома. Экономьте, и вы дотянете до зарплаты!");
            }
        } else if (moneyBeforeSalary.compareTo(BigDecimal.valueOf(30000)) < 0) {
            if (daysBeforeSalary.compareTo(BigDecimal.valueOf(10)) < 0) {
                OUT.println("Неплохо! Прикупите долларов и зайдите поужинать в классное место. :)");
            } else {
                OUT.println("Окей, пора в Макдак!");
            }
        } else {
            if (daysBeforeSalary.compareTo(BigDecimal.valueOf(10)) < 0) {
                OUT.println("Отлично! Заказывайте крабов!");
            } else {
                OUT.println("Неплохо! Прикупите долларов и зайдите поужинать в классное место. :)");
            }
        }
    }

    private static void choose() {
        int choice = IN.nextInt();
        String inType;
        switch (choice) {
            case 1 -> inType = "Rubles >> " + RUBLES;
            case 2 -> inType = "US Dollars >> " + RATE_USD;
            case 3 -> inType = "Euros >> " + RATE_EUR;
            case 4 -> inType = "British Pounds >> " + RATE_GBP;
            case 5 -> inType = "Japanese Yen >> " + RATE_JPY;
            default -> {
                OUT.println("Какая печаль, я пока не знаю такой валюты.\nПожалуйста, перезапустите программу и выберите валюту из списка :)");
                return;
            }
        }
        OUT.println("In type: " + inType);
    }

    private static void convert(BigDecimal moneyBeforeSalary) {
        OUT.println("Please choose the output currency");
        OUT.println("В какую валюту хотите конвертировать рубли? Доступные варианты: USD, EUR, JPY, GBP.");
        String currency = IN.next(); // считываю значения с помощью scanner
        if (currency.equals("RUB")) {
            OUT.println("Ваши сбережения в рублях: " + moneyBeforeSalary.divide(RUBLES, ROUNDING_MODE));
        }
        switch (currency) {
            case "RUS" -> OUT.println("Ваши сбережения в рублях:" + RUBLES);
            case "USD" -> OUT.println("Ваши сбережения в долларах: " + moneyBeforeSalary.divide(RATE_USD, ROUNDING_MODE));
            case "EUR" -> OUT.println("Ваши сбережения в евро: " + moneyBeforeSalary.divide(RATE_EUR, ROUNDING_MODE));
            case "GBP" -> OUT.println("Ваши сбережения в долларах: " + moneyBeforeSalary.divide(RATE_GBP, ROUNDING_MODE));
            case "JPY" -> OUT.println("Ваши сбережения в иенах: " + moneyBeforeSalary.divide(RATE_JPY, ROUNDING_MODE));
            default -> OUT.println("Валюта не поддерживается.");
        }
    }
}