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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Java

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

Q&A

解決済

3回答

13180閲覧

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

Tazusa

総合スコア41

Java

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

0グッド

0クリップ

投稿2018/04/19 14:54

編集2018/04/19 14:55

前提・実現したいこと

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

方針としては、まず一人一人のオブジェクトを作成し、配列に入れます。さらに一人一人の各教科の点数と合計をそれぞれを配列に入れます。全体の合計は新たに変数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; } }

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

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

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

java

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

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

java

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

とするだけで済みます。

投稿2018/04/19 15:15

swordone

総合スコア20649

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tazusa

2018/04/23 14:00 編集

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

2018/04/24 13:57

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

2018/04/24 14:47 編集

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

2018/04/24 14:48

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

2018/04/29 12: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; }
swordone

2018/04/29 12:59

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

2018/04/29 14:12

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

0

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

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

Java

1Student[] students = { 2 new Student("田中", 77, 62, 80), 3 new Student("山田", 60, 82, 89), 4 new Student("高橋", 86, 75, 90), 5 new Student("佐藤", 70, 75, 70), 6 new Student("小林", 90, 88, 89) 7}; 8 9int total = 0; 10for(Student student: students) { 11 total += student.getTotal(); 12 System.out.printf( 13 "名前: %s %d %d %d 合計 %d\n", 14 student.name, student.math, student.english, student.science, student.getTotal() 15 ); 16} 17 18System.out.println("平均:" + 1.0 * total / student.length);

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


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

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

投稿2018/04/19 15:06

編集2018/04/19 15:16
LouiS0616

総合スコア35658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tazusa

2018/04/23 13:20

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

2018/04/23 13:23

Tazusaさんのおっしゃる通りです。うっかりしていました。 ゲッターを経由するように読み替えてください。 なお、toStringを使う方法の場合は、各属性へのアクセスがStudentクラス内で完結するため、ゲッターは用意してもしなくても大丈夫です。
Tazusa

2018/04/23 13:58

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

0

java

1import java.util.LinkedHashMap; 2import java.util.Map; 3 4class Student { 5 private final String name; 6 private Map<String, Integer> scores; 7 8 Student(String name) { 9 this(name, new LinkedHashMap<String, Integer>()); 10 } 11 12 @SuppressWarnings("unchecked") 13 Student(String name, LinkedHashMap<String, Integer> scores) { 14 this.name = name; 15 this.scores = (Map<String, Integer>) scores.clone(); 16 } 17 18 @SuppressWarnings("serial") 19 Student(String name, int math, int eng, int physics) { 20 this(name, new LinkedHashMap<String, Integer>() { 21 { 22 put("数学", math); 23 put("英語", eng); 24 put("物理", physics); 25 } 26 }); 27 } 28 29 public String getName() { 30 return this.name; 31 } 32 33 public int getScore(String subj) { 34 Integer score = this.scores.get(subj); 35 if (score == null) { 36 score = 0; 37 } 38 return score; 39 } 40 41 public int getTotal() { 42 int total = 0; 43 for (Map.Entry<String, Integer> entry : this.scores.entrySet()) { 44 total += entry.getValue(); 45 } 46 return total; 47 } 48 49 public String toString() { 50 String str = "名前:" + this.name; 51 for (Map.Entry<String, Integer> entry : this.scores.entrySet()) { 52 str += ", " + entry.getKey() + ": " + entry.getValue(); 53 } 54 str += ", 合計: " + getTotal(); 55 return str; 56 } 57} 58 59public class Start { 60 public static void main(String[] args) { 61 // 生徒オブジェクト作成 62 Student[] students = { 63 // 名前, 数学、英語, 物理 64 new Student("田中", 77, 62, 80), 65 new Student("山田", 60, 82, 89), 66 new Student("高橋", 86, 75, 90), 67 new Student("佐藤", 70, 75, 70), 68 new Student("小林", 90, 88, 89) 69 }; 70 71 // 表示 72 for (Student s : students) { 73 System.out.println(s); 74 } 75 int total = 0; 76 for (Student s : students) { 77 total += s.getTotal(); 78 } 79 System.out.println( 80 String.format("平均: %.2f", 1.0 * total / (3 * students.length)) 81 ); 82 } 83}

実行例
イメージ説明

投稿2018/04/19 17:42

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tazusa

2018/04/23 13:28

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問