

以下のページの要件を元に、Javaでなんちゃって会員登録機能を作成しております。

[作って覚えるプログラミング精選課題集(Java基礎編） - レベル4
会員登録機能](https://qiita.com/s_hino/items/85ce20cb675484d300f0#%E3%83%AC%E3%83%99%E3%83%AB4-%E4%BC%9A%E5%93%A1%E7%99%BB%E9%8C%B2%E6%A9%9F%E8%83%BD)

コードを記述し終わり動かしてみた所、エラーが発生してうまくデータが出力されません。

[code]

    java.lang.IndexOutOfBoundsException: Index 333 out of bounds for length 1
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/Ml3B1.png)](https://i.stack.imgur.com/Ml3B1.png)

記述しているコードには問題はないと思うのですが、直し方がわかりません。  
お手数ですがご教授お願い致します。

2/24追記  
Register.javaのコードを修正した所、  
このようなデータが表示されました。  
[![画像の説明をここに入力](https://i.stack.imgur.com/7vL3z.png)](https://i.stack.imgur.com/7vL3z.png)

### ソースコード

Register.java

[code]

    package rensyu;
    
    import java.util.Date;
    import java.util.*;
    
    public class Register {
        static ArrayList<Kaiin> kaiinAll = new ArrayList<Kaiin>();
    
        public static void main(String[] args) {
            Register r = new Register();
            Scanner scan = new Scanner(System.in);
            System.out.println("何人登録しますか？");
            int i = scan.nextInt();
            int id = 0;
            String name = null;
            for (int j = 0; j < i; j++) {
                System.out.println("会員IDを入力してください");
                id = scan.nextInt();
                System.out.println("名前を入力してください");
                name = scan.next();
                kaiinAll.add(r.kaiinAdd(id, name));
                Kaiin lastElement = kaiinAll.get(kaiinAll.size() - 1);
                System.out.println(lastElement);
                
            }
    
        }
    
        private Kaiin kaiinAdd(int id, String name) {
            Kaiin k = new Kaiin();
            k.setId(id);
            k.setName(name);
            Date d = new Date();
            k.setAddDate(d);
            return k;
    
        }
    
    }
    
[/code]

Kaiin.java

[code]

    package rensyu;
    import java.util.Date;
    public class Kaiin {
        int id;
        String name;
        Date addDate;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Date getAddDate() {
            return addDate;
        }
        public void setAddDate(Date addDate) {
            this.addDate = addDate;
        }
    }
    
[/code]


CC BY-SA 4.0
2022-02-23T06:56:23.057
86530
2022-02-24T07:55:07.090
2022-02-24T05:36:20.530
50555
50555
question
java
ArrayList の操作・参照時にエラー java.lang.IndexOutOfBoundsException: Index 333 out of bounds for length 1


`kaiinAll.get(id)`
にて、idをキーとして可変長配列から要素を取得しているためです。これはHashMapや連想配列ではないので、挿入した順の配列です。(例えば、スクリーンショットの例外時の本来取得したい項目のインデックスは0です)

たとえば`ArrayList<Kaiin>`から特定のIDを持つ要素を取得したい場合、for-eachループが使えます。


CC BY-SA 4.0
2022-02-23T11:11:31.407
86536
2022-02-23T11:11:31.407
2376
86530
answer


[`ArrayList#add()`](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/util/ArrayList.html#add\(E\))
は、 **リストの最後** に、指定された要素を追加するメソッドです。

ですので、直前に追加した要素を取得するには、[`ArrayList#get()`](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/util/ArrayList.html#get\(int\))
の引数に、 **リストの最後** の要素を示す **インデックス** を渡せば良いです。

インデックスは0始まりなので、 **リストの最後** の要素を示す **インデックス** は `リストの要素数 - 1` になります。

まとめると、

[code]

    Kaiin lastElement = kaiinAll.get(kaiinAll.size() - 1);
    
[/code]

で直前に登録した会員オブジェクトを取得できます。

質問文の実装

[code]

    kaiinAll.get(id)
    
[/code]

は、インデックスとは無関係の値を引数にしています。

(コメントを受けて追記)

> 修正しましたが、うまく表示されませんでした。

`System.out.println()` の引数にオブジェクトを渡すと
[`toString()`](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/lang/Object.html#toString\(\))
メソッドにより生成された文字列が出力されます。`Kaiin` クラスは `toString()` メソッドを実装していないので、デフォルト実装

[code]

    getClass().getName() + '@' + Integer.toHexString(hashCode())
    
[/code]

が用いられます。  
これはおそらく期待する出力とは異なるでしょう。

解決策としては、`Kaiin`クラスで `toString()` をオーバライドして適切に実装を行う、ということが考えられます。

[code]

    public class Kaiin {
        // ...
    
        @Override
        public String toString() {
            // ここで出力する文字列を組み立てる
            return "TODO";
        }
    }
    
[/code]

(ただし、今回の課題は必ずしも `toString()` を利用すべし、というものでは無さそうにも見えます。)

* * *

なお、リンク先の課題は

> 出力はプログラムの最後にまとめて行ってください。

ということなので、最終的には "直前に登録した要素のインデックスは..."
というようなことは考えず、リストに登録されている全要素をループで一気に出力する、ということになるかと思います。


CC BY-SA 4.0
2022-02-23T23:47:35.770
86542
2022-02-24T07:55:07.090
2022-02-24T07:55:07.090
2808
2808
86530
answer