Kcatchup
@Kcatchup (KC atchaup)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

初心者です。JavaのListについて教えてください。

解決したいこと

現在、大学でJavaのリストについて学んでいるのですが、
課題でつまずいてしまい、助けていただきたく質問を投稿しました。

【やりたいこと】
1)Sample1クラスにObjectを定義
2)Sample2のメソッドを通じて、Sample3のリストに1)のObjectを渡す(追加する)
以上を通じて、Sample3内のリストを以下のようにアップデートしようとしています。

名前, 価格, 数量
[1] "芋", 200, 20
[2] "トマト", 100, 10
[3] "牛肉", 1000, 5
.
.
.

以下にサンプルコードを乗せていますが、
この内容で実行すると、Mainクラスに記載の<1>, <2>、
それぞれ以下の挙動になります。
<1> "芋", 200, 20 //正しく出力されます。
<2> IndexOutOfBoundsException //リストが作成されていないようです。

ゴールとしてはSample3のリストの内容自体を変えたいので、
<2>の結果と<1>の結果が一致するようにしたいです。

Sample2のGetter経由であればリストにObjectの追加ができているのに、
Sample3から直接リストを取り出そうとすると何も追加されていないのが
何故なのか自力ではわからず、、

原因と、何か良い解決策があれば教えていただけますでしょうか。

以下の様なクラス構成にすることや、Attributeをprivateにすることなど、
構成面は変えない前提でアドバイスを頂けますと幸いです。

初歩的なことで申し訳ありませんが、どうぞよろしくお願い致します。

サンプルコード

//追加したいObjectの形式を定義したクラス
class Sample1 {
    private String name;
    private int price;
    private int qty;
    
    //constructor
    Sample1 (String name, int price, int qty) {
    this.name = name;
    this.price = price;
    this.qty = qty;
    }
    
    //getter
    public String getName() {
        return name;
    }

    public int getPrice() {
        return price;
    }

    public int getQty() {
        return qty;
    }
}

//Objectを渡すメソッドを含むクラス
class Sample2 {
    private Sample3 sample3;

    //constructor
    public Sample2() {
        sample3 = new Sample3();
    }
    
    //getter
    public Sample3 getSample3() {
        return sample3;
    }
    
    //新しいObjectをSample 3に追加するメソッド
    public void addition(String name, int price, int qty) {
        //新しいSample1 objectの呼び出し
        Sample1 s1 = new Sample1(name, price, qty);
        //Sample3のリストへのObject追加
        sample3.setSample3(s1);
    }
}

//Objectを追加していくリストを含むクラス
class Sample3 {
    //Sample1のObjectで構成されるリストを定義
    private List<Sample1> targetList;
    
    //constructor(リストの初期化)
    public Sample3() {
        targetList = new ArrayList<>();
    }

    //getter
    public List<Sample1> getTargetList() {
        return targetList;
    }
    
    //setter(sample1をSample2から受け取って、リストに追加するようにしている)
    public void setSample3(Sample1 sample1) {
        this.targetList.add(sample1);
    }
}

public class Main {
    public static void main(String[] args){
        Sample2 s2 = new Sample2();
        Sample3 s3 = new Sample3();
        s2.addition("芋", 200, 20);
        s2.addition("トマト", 100, 10);
        s2.addition("牛肉", 1000, 5);

        //<1> Sample2からGetter経由で一つ目のObjectを出力した場合      
        System.out.println(s2.getSample3().getTargetList().get(0).getName());
        System.out.println(s2.getSample3().getTargetList().get(0).getPrice()); 
        System.out.println(s2.getSample3().getTargetList().get(0).getQty());  
    
        //<2> Sample3から直接一つ目のObjectを出力した場合 
        System.out.println(s3.getTargetList().get(0).getName());
        System.out.println(s3.getTargetList().get(0).getPrice());
        System.out.println(s3.getTargetList().get(0).getQty());
    }
}

1

3Answer

Comments

  1. @Kcatchup

    Questioner

    早速ご回答を頂きありがとうございます!

    Sample3内のsetter(*)で、
    Sample2からobjectを渡す
    →渡されたobjectをSample3内のリストに追加する。
    という挙動を意図していたのですが、これに加えてSample3内で、受け取ったobjectを追加するメソッドなどが必要ということでしょうか?

    *setter
    public void setSample3(Sample1 sample1) {
    this.targetList.add(sample1);
    }
  2. 既存の実装で正しいと思います。
    `s2` の持つ `sample3` と `s3` は別のインスタンスですから、片方にObjectを追加したからといってもう片方にも追加されたりはしません。
  3. @Kcatchup

    Questioner

    ありがとうございます!
    問題点を理解できました。

    質問させていただいたコードの構成にて、Sample3のリストに直接、Sample2のメソッドを用いてobjectを追加していく方法は何かありますでしょうか…?

  4. 申し訳ありませんが質問の意味がよくわかりません。
  5. @Kcatchup

    Questioner

    ご確認ありがとうございます。
    頭が整理できないまま質問してしまいすみません。ご放念ください。

    初めにアドバイス頂いた内容を見直した結果、本件解決することができました。
    ありがとうございました!

質問させていただいたコードの構成にて、Sample3のリストに直接、Sample2のメソッドを用いて>objectを追加していく方法は何かありますでしょうか…?

「Sample2のadditionメソッドを用いて、mainメソッドの2行目に書かれたs3のメンバ変数targetListに直接objectを追加する方法はありますか」という質問であっていますか?

質問があっていると仮定した場合、以下の対応で可能かと思います。

(1) Sample2に引数付きコンストラクタを追加

public Sample2(Sample3 s3) {
    sample3 = s3;
}

(2) Main関数の上2行を修正

Sample3 s3 = new Sample3();
Sample2 s2 = new Sample2(s3);
0Like

<2> IndexOutOfBoundsException //リストが作成されていないようです。

こちらが発生する理由は、s3.targetListが長さ0のListのためです(長さ0なのにs3.getTargetList().get(0).getName()のように先頭要素を取得しに行ってIndexOutOfBoundsExceptionが発生しています。)。

Main関数で定義しているs2.sample3とs3が別物(別インスタンス)と理解することでこの問題は解決するかと思います。
※System.out.printlnなどでインスタンスの中身を可視化することをお勧めします(ただそのままでは動かないと思いますので、ピンとこなければスルーしてください。)。

Main関数の1-2行目を下記のように書くのが想定どおりかと思いますが、なぜ動くようになるかは(他の人に説明するなど)理解した方がいいです。

Sample2 s2 = new Sample2();
Sample3 s3 = s2.getSample3();
0Like

Your answer might help someone💌