Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

インスタンス生成して他クラスに追加したリストの参照方法

つい最近始めた初心者なので用語の使い方が誤っていたらごめんなさい。

インスタンス内に作成されたリストを呼び出したいのですが、
以下のコードでは「test.Material@2a139a55」といった出力結果が帰ってきてしまいます。
「木」と返してもらうにはどのように書き換えれば良いのでしょうか。

□Materialクラス
private String name;
public Material(String name){this.name = name;}
public String GetName(){return name;}

□Productクラス
private String pname;
private List<Material>mlist = new ArrayList<>();
public Product(String pname){this.pname = pname;}
public Product(List<Material> mlist){this.mlist = mlist;} 
public void addMaterial(Material material){this.mlist.add(material);}
public List<Material> getmlist(){return mlist;}
public String getpname(){return pname;}

□メインクラス
Material m0 = new Material("木");
Material m1 = new Material("糸");
Material m2 = new Material("針");
Product p1 = new Product("釣り竿");
p1.addMaterial(m0);
p1.addMaterial(m1);
p1.addMaterial(m2);
List<Material>test = p1.getmlist();
System.out.println(test.get(0));

よろしくお願いいたします。

10

回答

4694

閲覧

10件の回答

評価

0

答えを質問しちゃだめだ。考え方を質問するんだ。

System.out.println()のソースを見ると、どのように表示しているのか見える。

評価

0

答えを質問しちゃだめだ。考え方を質問するんだ。

System.out.println()のソースを見ると、どのように表示しているのか見える。
できることは、何でもしてみるんだよ。

評価

0

回答ありがとうございます。質問者です。2時間ほど試行錯誤して、リストの番号を指定して単体でStringに代入すれば表示ができるということはなんとなく分かりました。
しかし、本文は短略化されたコードで、実際には複数のproductを作成し、指定されたproductのmaterialを全て表示するプログラムを作りたいと考えています。
その場合、for文を使い、メインメソッドでリストの長さを継続条件に指定する必要があるかと思いますが、リストの長さをメインメソッドから取得するにはどのような書き方をすればよろしいでしょうか。

評価

0

>リストの長さをメインメソッドから取得
まず、質問を見る側にとっては質問の文章および付されたソースコードが全てだということを、理解する必要がある。
君にとっては目の前にあるコードでも、他人には推測することしかできない。
このため、質問をする際に付するコードに求められるのは、「そのまま動き、問題が再現可能な、最低限の量」だ。
それに解説があれば、見る側は最低限の労力で質問者の悩みを把握できる可能性が高くなる。
これは今回の質問のに限らず、またプログラミングの質問に限らず、考えるべきことだ。

>2時間ほど試行錯誤して
問題によっては何日も何ヶ月も、試行錯誤するんだよ。
それを短くすることは考えるべきだが、「こんなに悩んだ」という感じに考えてはいけない。

>リストの長さをメインメソッドから取得する
クラスは「ある一連の情報を格納したもの」だが、それだけではなくその情報を参照・更新するのに必要な「操作(インターフェース)を伴ったもの」だ(無いものもあるが)。
リストの長さ、つまりいくつ情報が格納されているか。それはリスト自身が管理すべきものだ。

評価

0

あれ、最初の引用箇所は「本文は短略化されたコード」のつもりだったんだが、何で間違えたんだろう。まあいいか。

評価

0

ところで…JavaDocは知っている?知らないなら早急に調べるべし。

評価

0

>質問を見る側にとっては質問の文章および付されたソースコードが全てだということを、理解する必要がある
ソースコードを全文で表記します。
書き方の作法が間違っていたらすみません。

以下のDemoクラスにおいて、
//表示テスト ではp1のnameを取得できていますが、同じ理屈で
//配列テスト でp1のmlistの要素数・リストの内容を取得できないことが疑問です。(エラーがでます)
また、このやり方以外にmlistの内容を取得する方法が思いつきません。

□Demoクラス
package test;

public class Demo {

    public static void main(String[] args) {

        //インスタンス生成
        Material m0 = new Material("木");
        Material m1 = new Material("糸");
        Material m2 = new Material("針");
        Product p1 = new Product("釣り竿");
        Product p2 = new Product("裁縫道具");

        //p1のmlistへm0 m1 m2 を格納
        p1.addMaterial(m0);
        p1.addMaterial(m1);
        p1.addMaterial(m2);
        
        //p2のmlistへm1 m2 を格納
        p2.addMaterial(m1);
        p2.addMaterial(m2);

        //表示テスト
        System.out.println(p1.getpname());

        //配列テスト
        for(int i=0;i<p1.getmlist.size();i++){            
            System.out.println(p1.getmlist.get(i));
        }
    }
}

□Materialクラス
package test;

public class Material {
    private String name;
    public Material(String name){
        this.name = name;
    }
    public String GetName(){
        return name;
    }
}

□Productクラス
package test;

import java.util.ArrayList;
import java.util.List;

public class Product {
    //各変数の宣言
    private String pname;

    public Product(String pname){
        this.pname = pname;
    }

    private List<Material>mlist = new ArrayList<>();

    public Product(List<Material> mlist){
        this.mlist = mlist;
    }

    //リストへ追加するメソッド
    public void addMaterial(Material material){
        this.mlist.add(material);
    }

    //ゲッター
    public List<Material> getmlist(){
        return mlist;
    }

    public String getpname(){
        return pname;
    }
}

評価

0

getmlistメソッドの呼び出し方が間違っているだけですね。
よーくみてください、何かが足りないはず。

>(エラーがでます)
エラーの内容を書きましょう。
あなたはエラーの内容を見て知っていますが、質問を読む側にはわかりません。

評価

0

あー、メソッドやフィールド、その記述の仕方がアヤフヤなのか。

評価

0


import java.util.ArrayList;
import java.util.List;

public class Demo {

    public static void main(String[] args) {

        //インスタンス生成
        Material m0 = new Material("木");
        Material m1 = new Material("糸");
        Material m2 = new Material("針");
        Product p1 = new Product("釣り竿");
        Product p2 = new Product("裁縫道具");

        //p1のmlistへm0 m1 m2 を格納
        p1.addMaterial(m0);
        p1.addMaterial(m1);
        p1.addMaterial(m2);
        
        //p2のmlistへm1 m2 を格納
        p2.addMaterial(m1);
        p2.addMaterial(m2);

        //表示テスト
        System.out.println(p1.getpname());

        //配列テスト
        for(int i=0;i<p1.getmlist().size();i++){            
            System.out.println(p1.getmlist().get(i).GetName());
        }
    }
}


class Material {
    private String name;
    public Material(String name){
        this.name = name;
    }
    public String GetName(){
        return name;
    }

public String toString(){

return name;
}

}


class Product {
    //各変数の宣言
    private String pname;

    public Product(String pname){
        this.pname = pname;
    }

    private List<Material>mlist = new ArrayList<>();

    public Product(List<Material> mlist){
        this.mlist = mlist;
    }

    //リストへ追加するメソッド
    public void addMaterial(Material material){
        this.mlist.add(material);
    }

    //ゲッター
    public List<Material> getmlist(){
        return mlist;
    }

    public String getpname(){
        return pname;
    }
}



















表示テスト
では
     Product p1 = new Product("釣り竿");に於いてProduct内の
コンストラクタにてp1内のpnameに"釣り竿"が代入されgる
その後
p1.getpname()に於いては
自作メソッドのgetpname()を用いてProductオブジェクトである
p1内のコンストラクタで初期化した変数pnameを直接呼び出しているので
呼び出したp1オブジェクト内のpname"釣り竿"が表示される


p1内にpnameは一つしかないためそれを呼び出すp1.getpname()でpnameが表示される






配列テストでは
一行目に
  for(int i=0;i<p1.getmlist.size();i++){            
とあるがp1.getlist.size()で呼び出そうとしている
p1内のオブジェクト配列であるmlistの配列の長さを返すには
p1.getlist().size()と書かねばならない
getlistはメソッドであり()が後ろにつかないと使えない



二行目で
System.out.println(p1.getmlist.get(i));
と書いているが
上記同様
getlist()と書かないとgetlistメソッドは使えない
よってp1.getmlist.get(i)を
p1.getmlist().get(i)に書き換える
これは、オブジェクトp1内の変数mlistに入ったオブジェクト配列の中のi番目のオブジェクトを示している


ここでp1.getmlist.get(i)をSystem.out.println()内に入れて
System.out.println(p1.getmlist().get(i));
とすると
質問者が最初に既述したような
test.Material@2a139a55
のようなハッシュコード付きのオブジェクト名が表示される
これは
System.out.println()内に「オブジェクト単独」を指し示す変数を入れると

「そのオブジェクト内のtoString()メソッド」が呼び出されるため
今回示されている自作のオブジェクトであるMaterial内には
toStringメソッドがオーバーライドされていないため
Materialが何もしなくとも元から継承しているObject内の
toStringメソッドが呼び出され
その場合
System.out.println()内に入れた「オブジェクト単独」を指し示す変数は
「System.out.println()内に入れた単独オブジェクトの名前」@「そのオブジェクトに対応したハッシュコード」として表示される

今回表示されるのは
「p1.getmlist.get(i)が示すmlist内の一つのオブジェクトの名前」@「そのオブジェクトに対応したハッシュコード」

よって
mlist内には
Material m0 = new Material("木");
Material m1 = new Material("糸");
Material m2 = new Material("針");
において三つのオブジェクトが代入されているため
test.Material@????????(ハッシュコード)
test.Material@????????(ハッシュコード)
test.Material@????????(ハッシュコード)
ように表示される
m0,m1,m2オブジェクトは全て異なるため
表示されるハッシュコードも一つずつ全て異なる

System.out.println()内に「オブジェクト単独」を指し示す変数を入れて
今質問者が表示したがっている 「Material」内の「name」変数を表示するようにしたいなら
Material内に
name変数を表示するような内容にした
toString()メソッドを書き
Object内の
「System.out.println()内に入れた単独オブジェクトの名前」@「そのオブジェクトに対応したハッシュコード」
を表示するように書かれている
toString()メソッドをオーバーライドしなければならない

そのようなtoString()メソッドは


public String toString(){

return name;
}

と書く事ができる
これを
Materialクラス内に入れオーバーライドすると

//配列テスト
        for(int i=0;i<p1.getmlist().size();i++){            
            System.out.println(p1.getmlist().get(i));
        }
と書いても
Material内のname変数が


針      
のように並んで表示される





ここでは恐らくgetlist()でmlistを呼び出し
その上で
GetNameを用いてコンストラクタで初期化したnameを呼びたしたがっている
nameを呼び出したいなら
p1.getmlist().get(i).GetName()と書くべき

//配列テスト
        for(int i=0;i<p1.getmlist().size();i++){            
            System.out.println(p1.getmlist().get(i).GetName());
        }

と書き換えるだけで質問者の意図する結果は出るが

//配列テスト
        for(int i=0;i<p1.getmlist().size();i++){            
            System.out.println(p1.getmlist().get(i));
        }
とだけ書いた上で質問者が表示したい「name」変数の縦に並んだ表示を実現したいなら

この場合呼び出しているMaterialオブジェクトのクラスである
public class Material {
    private String name;
    public Material(String name){
        this.name = name;
    }
    public String GetName(){
        return name;
    }
}
内に


public String toString(){

return name;
}


を挿入し


public class Material {
    private String name;
    public Material(String name){
        this.name = name;
    }
    public String GetName(){
        return name;
    }

public String toString(){

return name;
}
}


のようにしてやる必要がある

上記ソースではtoString()をMaterial内に入れたが
//配列テスト
        for(int i=0;i<p1.getmlist().size();i++){            
            System.out.println(p1.getmlist().get(i).GetName());
        }
のようにオブジェクトではなくname変数を呼び出すメソッドを
System.out.println()内に入れているため
Material内のtoString(){~}部分は


なくても質問者が意図した通りに動く

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。