質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.60%

条件によってインスタンス配列を変えたい

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 1,240

score 15

前提・実現したいこと

switch文によってList<>の<>に入れる部分を変えて
(同時に読み込むファイルも設定)
BufferedReaderを使ってList<?>に入れたい

発生している問題・エラーメッセージ

どうすればいいのかわからなくなって混乱してます

該当のソースコード

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;


public class Main {
    public static void main(String[] args) throws Exception {
        int select = 0;
        String csv = "";
        System.out.println(" 0 … 文系 (国語、社会、英語)");

        switch(select) {    //CSVファイルの設定
            case 0:    csv = "studentArts.csv";
                    List<Arts> Subject = new ArrayList<>();
                    break;
            (・・・caseを増やす予定・・・)
        }
        FRead(csv, Subject);//エラー・Subject を変数に解決できません
        int size = list.size();//エラー・list を解決できません
        //listにcsvのデータを入れ、読み込んだ行の数をカウントする
}
    public static void FRead(String filename, List<> list) {//エラー・型 List<E> の引数の数が誤っています。引数 <> でパラメーター化できません
        File csv = new File(filename);
        String line;

        try {
            BufferedReader br = new BufferedReader(new FileReader(csv));
            while ((line = br.readLine()) != null) {
                list.add(line.split(", "));
            }
            br.close();

        } catch (Exception e) {
            System.out.println(e);
        }
    }
public class Arts extends Student {
    private int kokugo;    //国語
    private int shakai;    //社会
    private int eigo;        //英語

    Arts() {    //コンストラクタ(引数なし:フィールドの初期化)
        super.setStAll(0, "", "");
        this.setScAll(0, 0, 0);
    }

    Arts(int n) {    //コンストラクタ(引数あり:フィールドの手動更新)
        super.setNo(n);
        this.setNamePoint();
    }

    public int getKokugo() {
        return this.kokugo;
    }

    public void setKokugo(int kokugo) {
        this.kokugo= kokugo;
    }

    public int getshakai() {
        return this.shakai;
    }

    public void setShakai(int shakai) {
        this.shakai = shakai;
    }

    public int getEigo() {
        return this.eigo;
    }

    public void setEigo(int eigo) {
        this.eigo = eigo;
    }
}
public class Student {
    private int no;
    private String name;
    private String gender;

    public int getNo() {
        return this.no;
    }

    public void setNo(int no) {
        this.no = no;
    }
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return this.gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void setStAll(int no, String name, String gender) {
        this.no = no;
        this.name = name;
        this.gender = gender;
    }
}
studentArts.csv
1, Aiba, 男, 46, 81, 48
2, Inoue, 女, 49, 64, 95
3, Ueda, 男, 51, 31, 45

補足情報(FW/ツールのバージョンなど)

java8
Eclipse4.10.1

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • jimbe

    2019/03/09 21:57

    「Javaでmainメソッドからreadメソッドを呼び出してArrayにcsvの内容を入れて返したい」
    https://teratail.com/questions/177118
    こちらからの続きでしょうか. 参考としてリンクを付けておいて頂けると, 回答する側にコードの出所が分かって良いかと思います.

    キャンセル

  • Blue-sea

    2019/03/12 11:22

    分かりました。
    次からはそうするようにします

    キャンセル

回答 4

checkベストアンサー

+1

switch文によってList<>の<>に入れる部分を変えて
(同時に読み込むファイルも設定)
BufferedReaderを使ってList<?>に入れたい

この操作がswitch-case内で完結するなら可能です。

        switch(select) {    //CSVファイルの設定
            case 0:
                csv = "studentArts.csv";
                List<Arts> Subject = new ArrayList<>();
                FRead(csv, Subject);  //これも正直よくわからんが…
                int size = list.size();
                break;
            (・・・caseを増やす予定・・・)
        }


しかしこれではほとんど意味がないでしょう。かといってswitchの外に持っていこうとすると、各caseで異なるListの型が出てくるので、それをswitchの外で扱おうとするなら、その型の正体を持ち越すことができません。
何とかしようとするなら私にはこういうやり方しか思いつきません。

List<? extends Student> students;
String csv;
switch(select) {
    case 0:
        csv = "studentArts.csv";
        students = new ArrayList<Arts>();
        FRead(csv, students);
        int size = list.size();
        break;

}


しかしこれも結局型情報が消えるので意味があまりありません。

おそらく、文系・理系別にどうこうしたいということでしょうから、
Studentの方にその情報を持たせ(文系・理系を表すフィールドをStudentクラスに設ける)、
一緒のList<Student>に詰めるという手法が現実的ではないかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/12 11:25

    これを参考にmainの始めにArts[] Art = new Arts[list.size]; を宣言してみたらコンパイルエラーは起きなくなりました。
    他にSciences[] Sci = new Sciences[list.size];もあります。
    これらをswitchでどちらかを実行したとき、使われなくても大丈夫なのでしょうか?

    キャンセル

+1

まずは4点のコンパイルエラーを解決したらどうでしょう。

たくさんの問題点をそのままにしておくとBlue-seaさんの中でどうすればいいのかわからなくなって整理がつかなくなります。

RPGでボスを倒しに行くことしか考えてないため、その辺のモンスターから総攻撃を受け続けているのと近いイメージですね。まずその辺のモンスターを一掃してから次のステップに行きましょう。

BufferedReaderを使ってList<?>に入れたい

BufferedReaderのreadLineメソッドからもらえる値の型は文字列です。
文字列からList<?>に変換するためのクラスを、既存のライブラリから持ってくるか自作する必要があります。

自作されたかは存じませんが、おそらく、FReadはあくまでList<string[]>を取るためのメソッドなのではないでしょうか?

    public static void FRead<T>(String filename, List<string[]> list) {
        String line;

        try {
            BufferedReader br = new BufferedReader(new FileReader(csv));
            while ((line = br.readLine()) != null) {
                list.add(line.split(", "));
            }
            br.close();

        } catch (Exception e) {
            System.out.println(e);
        }
    }
 public static void main(String[] args) throws Exception {
        int select = 0;
        String csv = "";
        System.out.println(" 0 … 文系 (国語、社会、英語)");

        List<string[]> list = new ArrayList<>
        FRead(csv, list);
        int size = list.size();

        //NOTE: select = 何をキーにして分岐をする?読み込む?ファイル名?

        switch(select) {    
            case 0:
                    csv = "studentArts.csv";
                    List<Arts> Subject = new ArrayList<>();
                    //TODO:listに入っているstring[]をArtsに変える処理を追加
                    break;
            (・・・caseを増やす予定・・・)
        }
 }

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/08 13:55

    ネットで調べてきになっていたのですが、
    List<Art>の中身は
    int[] Art = new int[?(とりあえず20は設定し、データによって変わる)]
    といった感じにArtが配列化したものと考えていいのでしょうか?

    キャンセル

  • 2019/03/08 15:34 編集

    知りたいことが何か要領を得られませんでしたが、リストと配列は違うデータ構造です。

    int[] Artの場合、あくまで「int型の配列」です。
    List<Art>の場合、あくまで「Art型のリスト」です。

    List<Art> SubjectとArt[] Subjectはどちらも「Art型が入ったデータ構造」と考えて良いですが、Listと配列は別物です。

    int[] Artは配列の型がArtなのではなく、変数名がArtなだけなので、全然別物です。

    キャンセル

  • 2019/03/12 11:31

    なるほど、勉強になります。
    知恵を貸していただきありがとうございました

    キャンセル

+1

switch文によってList<>の<>に入れる部分を変えて
(同時に読み込むファイルも設定)
BufferedReaderを使ってList<?>に入れたい

おそらく、public static void FRead(String filename, List<この中をクラス型としたいが特定のクラスだけではなく複数のクラスに対応> list)
それと同時にこの複数のクラスは.csvファイルにより決定する。
なので、List<>という書き方をし<この中>を書かなかった。なのでエラーが出てしまいます。
という事でOKでしょうか?

私もJavaは浅いので分かりませんがたぶん、できないと思います。
switch文で分けその先でそれぞれ固定のList<Arts>などとするしかありません。
固定の引数であるならできます。
引数渡しではありませんが例えばのサンプルを書いときます。
元のコードを基準に書いています。あしからず。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
//import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class readmain {
    private static List<Arts> list = new ArrayList<Arts>();
    private static List<Tabemono> tlist = new ArrayList<Tabemono>();
    private static Arts arts;
    private static Tabemono tabe;

    public static void main(String[] args) throws Exception{
        int select = 1; //今回はこれが目的ではないのでファイル選択はここで直接変更する事とする。
        String csv = "";
        System.out.println("0 … 文系 (国語、社会、英語)");
        System.out.println("1 … 食物系 (食べ物名)");

        switch(select) { //CSVファイルの設定
            case 0:
                csv = "C:/TestFolder/studentArts.csv";
                FRead(csv, select);
                listout(select);
                //List<Arts> Subject = new ArrayList<Arts>();
                break;
                //(・・・caseを増やす予定・・・)
            case 1:
                csv = "C:/TestFolder/tabemono.csv";
                FRead(csv, select);
                listout(select);
                break;
            default:
                System.out.println("ファイルが存在しない番号を選びました。");
                break;
        }
        //int size = Subject.size();//エラー・list を解決できません
        //listにcsvのデータを入れ、読み込んだ行の数をカウントする

    }

    private static void FRead(String filename, int sele) {
        File csv = new File(filename);
        String line;

        try {
            BufferedReader br = new BufferedReader(new FileReader(csv));
            while ((line = br.readLine()) != null) {
                String[] onegyo = line.split(", "); //一旦配列に入れる。もっと良い方法があれば良いが。
                switch(sele) {
                    case 0:
                        if (onegyo[0].startsWith("\uFEFF")) {
                            arts = new Arts(Integer.valueOf(onegyo[0].substring(1,onegyo[0].length())),onegyo[1],onegyo[2],Integer.valueOf(onegyo[3]),Integer.valueOf(onegyo[4]),Integer.valueOf(onegyo[5]));
                        } else {
                        //arts = new Arts();新しい実体を作成。それぞれの実体にデータを入れる。
                        //1つの実体を使いまわしその中にsetterを使い入れてもすべて最終のデータとなる
                        arts = new Arts(Integer.valueOf(onegyo[0]),onegyo[1],onegyo[2],Integer.valueOf(onegyo[3]),Integer.valueOf(onegyo[4]),Integer.valueOf(onegyo[5]));
                        //↑1行の代わりに以下の7行を使っても同じ。
                        //arts = new Arts();
                        //arts.setNo(Integer.parseInt(onegyo[0]));
                        //arts.setName(onegyo[1]);
                        //arts.setGender(onegyo[2]);
                        //arts.setKokugo(Integer.parseInt(onegyo[3]));
                        //arts.setShakai(Integer.parseInt(onegyo[4]));
                        //arts.setEigo(Integer.parseInt(onegyo[5]));
                        }
                        list.add(arts);
                        break;
                    case 1:
                        //Windowsのメモ帳などでUTF-8で保存した場合1行目の先頭にはBOMと言う物が付いている
                        if (onegyo[0].startsWith("\uFEFF")) {
                            //付いている場合は除いた2文字目から取る
                            tabe = new Tabemono(Integer.parseInt(onegyo[0].substring(1,onegyo[0].length())), onegyo[1]);
                        }else {
                            //付いていない場合はそのまま取る
                            tabe = new Tabemono(Integer.parseInt(onegyo[0]), onegyo[1]); //Integer.valueOf(onegyo[0])
                        }

                        tlist.add(tabe);
                        break;
                }
            }
            br.close();

        } catch (Exception e) {
            System.out.println(e);
        }
    }

    private static void listout(int sele) {
        Arts wcls;
        Tabemono twcls;
        String ws = "";

        switch(sele) {
            case 0:
                for (int a = 0; a < list.size(); a++) {
                    wcls = list.get(a);
                    ws = String.valueOf(wcls.getNo()) + ", " + wcls.getName() + ", " + wcls.getGender() + ", ";
                    ws += String.valueOf(wcls.getKokugo()) + ", " + String.valueOf(wcls.getShakai()) + ", " + String.valueOf(wcls.getEigo());
                    System.out.println(ws);
                }
                break;
            case 1:
                for (int a = 0; a < tlist.size(); a++) {
                    twcls = tlist.get(a);
                    ws = String.valueOf(twcls.getTno()) + ", " + twcls.getNamae();
                    System.out.println(ws);
                }
                break;
        }

        //System.out.println(System.getProperty("file.encoding"));
    }
}
/** 教科クラス
 */
public class Arts extends Student{
    private int kokugo;    //国語
    private int shakai;    //社会
    private int eigo;    //英語

    //コンストラクタ(引数なし:フィールドの初期化のみ)
    public Arts() {
        super.setStAll(0, "", "");
        this.setScAll(0, 0, 0);
    }

    //コンストラクタ(実体の作成と同時に引数でフィールドにセット)
    public Arts(int no , String name, String gender, int kokugo,int shakai,int eigo) {
        this.no = no;
        this.name = name;
        this.gender = gender;
        this.kokugo = kokugo;
        this.shakai = shakai;
        this.eigo = eigo;
    }

    //コンストラクタ(引数あり:フィールドの手動更新)
    //このコンストラクタは何をやりたかったのか不明なので保留
    public Arts(int n) {
        super.setNo(n);
        //this.setNamePoint(); //フィールドに宣言されてもおらず不明
    }

    public int getKokugo() {
        return this.kokugo;
    }

    public void setKokugo(int kokugo) {
        this.kokugo= kokugo;
    }

    public int getShakai() {
        return this.shakai;
    }

    public void setShakai(int shakai) {
        this.shakai = shakai;
    }

    public int getEigo() {
        return this.eigo;
    }

    public void setEigo(int eigo) {
        this.eigo = eigo;
    }

    public void setScAll(int kokugo,int shakai,int eigo) {
        this.kokugo = kokugo;
        this.shakai = shakai;
        this.eigo = eigo;
    }

}
/** 生徒クラス(基底クラス)
 */
public class Student {
    protected int no; //Studentクラスと継承先のクラスで使えるようにprotectedで宣言
    protected String name;
    protected String gender;

    //コンストラクタ(初期化)
    public Student() {
        this.setStAll(0, "", "");
    }

    //コンストラクタ(同時にフィールドに代入。)
    public Student(int no, String name, String gender) {
        this.no = no;
        this.name = name;
        this.gender = gender;
    }

    public int getNo() {
        return this.no;
    }

    public void setNo(int no) {
        this.no = no;
    }
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return this.gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void setStAll(int no, String name, String gender) {
        this.no = no;
        this.name = name;
        this.gender = gender;
    }
}

以下追加
Tabemono.java

/**食べ物クラス**/
public class Tabemono {
    private int _tno;
    private String _namae;

    public Tabemono() {
        this._tno = 0;
        this._namae = "";
    }

    public Tabemono(int tno, String namae) {
        this._tno = tno;
        this._namae = namae;
    }

    public int getTno() {
        return this._tno;
    }

    public void setTno(int value) {
        this._tno = value;
    }

    public String getNamae() {
        return this._namae;
    }

    public void setNamae(String value) {
        this._namae = value;
    }
}


追加csv(Tabemono.csv)

1, りんご
2, さしみ
3, ステーキ

ちなみに、int[] Art;はArtという単なる配列であり、Artsクラスとは何の関係もない事になります。
int[] abc;と同じです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/12 11:30

    解答ありがとうございます。
    インスタンス型配列を使うことで解決しました。

    キャンセル

+1

import java.io.*;
import java.util.*;

public class Main {
  public static void main(String[] args) throws Exception {
    int select = 0;
    String filename = null;
    CsvRowObjectsFactory factory = null;
    System.out.println(" 0 … 文系 (国語、社会、英語)");

    switch(select) {    //CSVファイルの設定
      case 0:
        filename = "studentArts.csv";
        factory = new ArtsCROFactory();
        break;
        //(・・・caseを増やす予定・・・)
    }
    List<? extends Student> list = readCSV(filename, factory);
    int size = list.size();
    System.out.println("size="+size);
  }
  public static List<? extends Student> readCSV(String filename, CsvRowObjectsFactory factory) throws IOException {
    try(BufferedReader br = new BufferedReader(new FileReader(new File(filename)))) {
      for (String line; (line = br.readLine()) != null;) factory.add(line.split(", "));
    }
    return factory.finish();
  }

  interface CsvRowObjectsFactory {
    void add(String[] items);
    List<? extends Student> finish();
  }
  static class ArtsCROFactory implements CsvRowObjectsFactory {
    private List<Arts> list = new ArrayList<Arts>();
    @Override public void add(String[] items) {
      Arts arts = new Arts();
      arts.setStAll(Integer.parseInt(items[0]), items[1], items[2]);
      arts.setKokugo(Integer.parseInt(items[3]));
      arts.setShakai(Integer.parseInt(items[4]));
      arts.setEigo(Integer.parseInt(items[5]));
      list.add(arts);
    }
    @Override public List<Arts> finish() {
      List<Arts> tmp = new ArrayList<>(list);
      list.clear();
      return tmp;
    }
  }
}

わざわざ CSV を読む部分を共通にする必要があるのかが疑問に思います.
Arts extends Student も違和感を感じますが, とりあえずという感じでしょうか.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/12 11:29

    解答ありがとうございます。
    確かにそうですね・・・。
    csvファイルを増やしてswitch文を使って
    読み分けることにしました。

    キャンセル

  • 2019/03/12 16:28

    Arts の他に Sciences もあるということで, switch に Sciences のコードも付け足された上で, どちらの場合も csv を読み込んだ後の処理を追加してみて頂けると, Arts, Sciences, Student の各クラス設計および CSV ファイルの読み込みメソッドの内容等, どういう形が出来るのかの回答も出るかと思います.

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る