ローン計算ツール

独学した内容で、Javaでローン計算ツールを作りました。
動くものにはなっていますが、直すべき部分が多々あるかと思います。
ご指摘いただけると幸いです。

## 行動の目的
### ローン計算ツールを作る
一年毎のデータを表示する(毎月表示だとうるさい)
## 何をしたか
### 以下3つのクラスを作成
<details><summary>メインクラス</summary>

```java:Loan.java
package pack2537;

import java.util.Scanner;

// 元利均等返済メインクラス
public class Loan{
    public static void main(String[] args){
        int balance;                            // 借入金額
        int duration;                           // 返済期間
        double rate;                            // 年利(%)
        Scanner stdIn = new Scanner(System.in);

        do{
            System.out.println("借入金額");
            balance = stdIn.nextInt();                              // 正の整数を入力
        }while(balance <= 0);

        do{
            System.out.println("返済期間(年)");
            duration = stdIn.nextInt();                             // 正の整数を入力
        }while(duration <= 0);

        do{
            System.out.println("年利(%)");
            rate = stdIn.nextDouble();                              // 0より大きい数値を入力
        }while(rate <= 0);

        LevelPayment lp = new LevelPayment(balance,duration,rate);  // LevelPayment型インスタンスを生成 
        lp.showAll();
    }
}
```

</details>

<details><summary>元利均等返済クラス</summary>

```java:LevelPayment.java
// 元利均等返済
package pack2537;

public class LevelPayment{
    private int balance;            // 借入額
    private int duration;           // 返済年数
    private double[] rates;         // 各年に適用する年利(%)
    private AnnualData[] ad;        // 一年毎のデータ
    
  // コンストラクタ
  public LevelPayment(){}
  
  public LevelPayment(int balance,int duration,double rate){   // (借入額,返済年数,年利(%))
    this.balance = balance;
    this.duration = duration;
    this.rates = new double[duration];
    this.setRates(rate);
    this.ad = this.generate(new AnnualData[duration]);
  }

  // セッタ
  public void setRates(double rate){                          // rates[0]を設定し、以降を初期化
    this.rates[0] = rate;
    for(int i = 1;i < this.rates.length;i++){
      this.rates[i] = -1.0;
    }
  }

  public void setRates(double rate,int i){
    this.rates[i] = rate;
  }

  // AnnulData配列を返済年数分生成するメソッド(AnnualData[返済年数])
  public AnnualData[] generate(AnnualData[] ad){
    ad[0] = new AnnualData(this.balance,this.calc(0),this.rates[0]);

    for(int i = 1;i < ad.length;i++){
      int n = i - 1;                                                    // 前年分のデータの要素数
      ad[i] = new AnnualData(ad[n].getBalance(),ad[n].getSumPayment(),ad[n].getPayment(),ad[n].getRate());
    }
    return ad;
  }


  // 毎月返済額を返すメソッド(ratesの要素)
  public int calc(int a) {
    int n = this.duration * 12 ;                             // 返済回数
    double interest = this.rates[a] * 0.01 / 12 ;                // 月利
    
    double x = 1.0 ;
    for (int i = 0 ; i < n ; i++){
      x = (1 + interest) * x ;                               // (1 + 月利)^(返済回数)
    }
    int p = (int) (this.balance * interest * x / (x - 1)) ;
    return p ;
  }

  // 全ての一年毎のデータを表示するメソッド
  public void showAll(){
    System.out.println("借り入れ後経過年数/一月当たりの返済額/年末時支払い済み総額/年末時残高/適用金利");
    for(int i = 0 ; i < this.ad.length ; i++){
        System.out.print((i + 1) + "年目/");
      this.ad[i].show();
    }
  }
}
```

</details>

<details><summary>一年毎のデータを扱うクラス</summary>

```java:AnnualData.java
// 一年毎のデータ
package pack2537;

public class AnnualData {
    private int payment;           // 当年の一月当たりの返済額
    private int sumPayment;        // 年末時支払い済み総額
    private int balance;           // 年末時ローン残高
    private double rate;           // 当年の年利(%)

    // コンストラクタ
    public AnnualData(){}

    // (年始時ローン残高,一月当たりの返済額,年利(%))
    public AnnualData(int balance,int payment,double rate){
        this(balance,0,payment,rate);
    }

    // (年始時ローン残高,支払い済み総額,一月当たりの返済額,年利(%))
    public AnnualData(int balance,int sumPayment,int payment,double rate){
        this.payment = payment;
        this.sumPayment = sumPayment + payment * 12;
        this.rate = rate;
        this.balance = this.calc(balance);
    }

    // ゲッタ
    public int getPayment(){return payment;}
    public int getSumPayment(){return sumPayment;}
    public int getBalance(){return balance;}
    public double getRate(){return rate;}
  
    // 4つのフィールドを/区切りで表示するメソッド
    public void show(){
        System.out.println(this.payment + "円/" + this.sumPayment + "円/" + this.balance + "円/" + this.rate + "%");
    }
    
    // 年度末時のローン残高を計算するメソッド
    public int calc(int balance){
        double r = this.rate * 0.01 / 12 + 1;   // 月利
        for(int i = 0;i < 12;i++){
            balance = (int)(balance * r - this.payment);
        }
        if(balance < this.payment){
            this.sumPayment += balance;
            System.out.println("最終月返済額/" + (this.payment + balance) + "円");
            balance = 0;
        }    
        
        return balance;
    }
}
```

</details>

[計算式の参考](https://graviness.hatenablog.com/entry/2025/01/09/130212)

## 行動の結果何を考えたか
実行結果を[Web上のツール](https://keisan.casio.jp/exec/system/1256183644)と比較したところ、総返済額で2円ほど誤差が発生しましたが、最終支払月で数百円の丸めが発生するようなので、許容範囲としました。
### 本来であれば例外処理を記述するべき
### 発生したインシデント
クラスファイルのファイル名間違い
==とすべきところを=と誤記
メソッド内の処理を書いたあとreturn忘れ
generate()を実行し忘れ、実行時例外
## 次に何をしたいか
GUIを用いて扱いやすくする
### 利息を変更する機能の実装
LevelPaymentクラスに利息を変更するためのフィールドを持たせましたが、未実装

ここまでお読みいただき、ありがとうございました。