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

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

ただいまの
回答率

90.61%

  • Java

    13538questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクトを配列に入れて各要素を表示をスマートにやりたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 315

Tazusa

score 22

 前提・実現したいこと

五人の名前と、数学、英語、物理のテストの結果をそれぞれ表示したうえで集計し、平均を出すプログラムを書いています。

方針としては、まず一人一人のオブジェクトを作成し、配列に入れます。さらに一人一人の各教科の点数と合計をそれぞれを配列に入れます。全体の合計は新たに変数sumを宣言し、最後に表示させています。

今まであまり長いコードを書いたことがなかったからかもしれませんが、この動きにここまで長いコードが必要なものなのでしょうか。

よりスマートにできる方法があれば教えていただきたいです。
よろしくお願いします。

(セッタ・ゲッタは今回は使用しませんが、必要になる場合もあるかもしれないということで一応書いています。)

 該当のソースコード

public class Start {
    public static void main(String[] args) {

//生徒オブジェクト作成
        Student tanaka = new Student("田中", 77, 62, 80);
        Student yamada = new Student("山田", 60, 82, 89);
        Student takahashi = new Student("高橋", 86, 75, 90);
        Student satoh = new Student("佐藤", 70, 75, 70);
        Student kobayashi = new Student("小林", 90, 88, 89);

//オブジェクトを配列に入れる
        Student[] student = {tanaka, yamada, takahashi, satoh, kobayashi};

//名前、点数、各人の合計を配列に入れるために配列を作る
        String[] names = new String[5];
        int[] mathPoint = new int[5];
        int[] engPoint = new int[5];
        int[] sciPoint = new int[5];
        int[] totalPoint = new int[5];

//配列に入れる
        for(int i = 0; i < student.length; i++) {
            names [i] = student[i].getName();
            mathPoint[i] = student[i].getMath();
            engPoint[i] = student[i].getEnglish();
            sciPoint[i] = student[i].getScience();
            totalPoint[i] = student[i].getTotal();
        }

//表示
        for(int i = 0; i < student.length; i++) {
        System.out.println("名前:" + names[i] + " " + mathPoint[i] + " " + engPoint[i] + " "
        + sciPoint[i] + " 合計:" + totalPoint[i]);
        }

//平均を出すために全体の合計を出す
        int sum = 0;
        for(int i = 0; i < student.length; i++) {
            sum += student[i].getTotal();
        }

        System.out.println("平均:" + sum/student.length);
    }
}
public class Student {

    //メンバ変数宣言
    private String name;
    private int math;
    private int english;
    private int science;

    //コンストラクタ

    Student(){
        this("無記名");
    }

    Student(String name){
        this(name, 0);
    }

    Student(String name, int math){
        this(name, math, 0);
    }

    Student(String name, int math, int english){
        this(name, math, english, 0);
    }

    Student(String name, int math, int english, int science){
        this.name = name;
        this.math = math;
        this.english = english;
        this.science = science;
    }

    //セッタ
    public void setName(String name){
        this.name = name;
    }

    public void setMath(int math) {
        this.math = math;
    }

    public void setEnglish(int english) {
        this.english = english;
    }

    public void setScience(int science) {
        this.science = science;
    }

    public String getName() {
        return name;
    }

    public int getMath() {
        return math;
    }

    public int getEnglish() {
        return english;
    }

    public int getScience() {
        return science;
    }
//合計を出す
    public int getTotal() {
        return math + english + science;
    }

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+6

せっかくStudentクラスでまとめて管理しているのに、バラバラに配列に入れる意味はありません。

「表示」についてはStudentクラスでtoString()メソッドをオーバーライドすればすっきりします。

// Studentクラス内
public String toString() {
    return "名前:" + name + " " + math + " " + english + " " + science + " 合計:" + getTotal();
}

こうしておけば、表示の時

for (Student s : student) {
    System.out.println(s);
}


とするだけで済みます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/23 22:59 編集

    ありがとうございます。
    toString()メソッドについては不勉強でした。
    これをきっかけに使い方を覚えたいと思います。

    キャンセル

  • 2018/04/24 22:57

    toString()を使ってみようとしたのですが、
    Startクラスで平均を求めるために
    System.out.println("平均: " + getTotal()/student.length);
    を打つと「getTotal()は型Startで未定義です」というエラーが出てしまいます。
    なぜこのようなエラーがでてしまうのでしょうか。

    キャンセル

  • 2018/04/24 23:01 編集

    勘違いでコメントしました。

    キャンセル

  • 2018/04/24 23:48

    そのエラーの通り、getTotal()というメソッドがStartクラスで定義されていないからです。
    仮にStudentクラスのインスタンスのgetTotalを呼んだとしても、それはその一人の合計点であって全員の合計点ではないですよね?

    キャンセル

  • 2018/04/29 21:57

    おっしゃる通りでした。解決するためにはStudentクラスに平均を求めるメソッドを追加したらよいかと思ったのですが、studentを変数として解決できませんと言われてしまいます。
    Startクラスで定義しているので問題ないのではないかと思っていたのですが...
    public int getAve() {
    int sum = 0;
    for(int i = 0; i < student.length; i++) {
    sum += student[i];
    }
    returns sum/student.length;
    }

    キャンセル

  • 2018/04/29 21:59

    studentはmainメソッドのローカル変数なので、引数として渡さない限り他のメソッドからアクセスできません。

    キャンセル

  • 2018/04/29 23:12

    mainメソッドの中のものもローカル変数として扱われると考えていませんでした。ありがとうございます。

    キャンセル

+4

よりスマートにできる方法があれば教えていただきたいです。

変数の大半が不要なように思います。
その他、拡張for文やprintfを取り入れられそうです。

Student[] students = {
    new Student("田中", 77, 62, 80),
    new Student("山田", 60, 82, 89),
    new Student("高橋", 86, 75, 90),
    new Student("佐藤", 70, 75, 70),
    new Student("小林", 90, 88, 89)
};

int total = 0;
for(Student student: students) {
    total += student.getTotal();
    System.out.printf(
        "名前: %s %d %d %d 合計 %d\n",
        student.name, student.math, student.english, student.science, student.getTotal()
    );
}

System.out.println("平均:" + 1.0 * total / student.length);

適当に書いているので、バグを仕込んでいるかもしれません。悪しからず。


余力があるのなら、StudentクラスでtoStringメソッドをオーバーライドすると良いでしょう。

また、各生徒の総得点はコンストラクタで計算してしまってよいようにも思います。
(この場合、セッターの実装を少し工夫する必要があります。)

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/23 22:20

    お礼が遅くなりましたが、、ありがとうございました。
    一つ質問なのですが、student.nameやstudent.mathはStartクラスからアクセスできるのでしょうか?
    privateだとそのクラス外から直接アクセスできないという理解だったのですが…

    キャンセル

  • 2018/04/23 22:23

    Tazusaさんのおっしゃる通りです。うっかりしていました。
    ゲッターを経由するように読み替えてください。

    なお、toStringを使う方法の場合は、各属性へのアクセスがStudentクラス内で完結するため、ゲッターは用意してもしなくても大丈夫です。

    キャンセル

  • 2018/04/23 22:58

    ありがとうございます!
    かなりいらない変数が多かったですね。参考になりました。

    キャンセル

+2

import java.util.LinkedHashMap;
import java.util.Map;

class Student {
    private final String name;
    private Map<String, Integer> scores;

    Student(String name) {
        this(name, new LinkedHashMap<String, Integer>());
    }

    @SuppressWarnings("unchecked")
    Student(String name, LinkedHashMap<String, Integer> scores) {
        this.name = name;
        this.scores = (Map<String, Integer>) scores.clone();
    }

    @SuppressWarnings("serial")
    Student(String name, int math, int eng, int physics) {
        this(name, new LinkedHashMap<String, Integer>() {
            {
                put("数学", math);
                put("英語", eng);
                put("物理", physics);
            }
        });
    }

    public String getName() {
        return this.name;
    }

    public int getScore(String subj) {
        Integer score = this.scores.get(subj);
        if (score == null) {
            score = 0;
        }
        return score;
    }

    public int getTotal() {
        int total = 0;
        for (Map.Entry<String, Integer> entry : this.scores.entrySet()) {
            total += entry.getValue();
        }
        return total;
    }

    public String toString() {
        String str = "名前:" + this.name;
        for (Map.Entry<String, Integer> entry : this.scores.entrySet()) {
            str += ", " + entry.getKey() + ": " + entry.getValue();
        }
        str += ", 合計: " + getTotal();
        return str;
    }
}

public class Start {
    public static void main(String[] args) {
        // 生徒オブジェクト作成
        Student[] students = {
                // 名前, 数学、英語, 物理
                new Student("田中", 77, 62, 80),
                new Student("山田", 60, 82, 89), 
                new Student("高橋", 86, 75, 90),
                new Student("佐藤", 70, 75, 70), 
                new Student("小林", 90, 88, 89)
         };

        // 表示
        for (Student s : students) {
            System.out.println(s);
        }
        int total = 0;
        for (Student s : students) {
            total += s.getTotal();
        }
        System.out.println(
                String.format("平均: %.2f", 1.0 * total / (3 * students.length))
        );
    }
}


実行例
イメージ説明

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/23 22:28

    ありがとうございます。
    MapクラスやLinkedHashMapはまだ未学習でした。
    またさらに勉強してもう一度katoyさんの答えをもう一度読ませていただきたいと思います。

    キャンセル

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

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

関連した質問

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

  • Java

    13538questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。