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

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

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

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

Q&A

解決済

2回答

994閲覧

配列の重複チェックができない

TaWa

総合スコア9

Java

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

0グッド

0クリップ

投稿2020/07/12 12:32

編集2020/07/16 14:46

JAVAで学生の名前、ID、年齢を配列に入れ、重複チェック後に平均年齢を求めるプログラムを作っています。現在のところ、平均値を求めることはできるようになったのですが、重複チェックができていません。以下現状のプログラムです。

public class Student {

public String name;// =""; //名前 String studentID;// =""; //学生ID public int age ; //年齢 public String id;//="";

public Student(String name, String id, int age) {
this.name = name;
this.studentID = id;
this.age = age;
}
public int getage(){
return age;
}
}

public class StudentInfo {

public static final int MAX_COUNT=100; //取り扱えるStudentの最大数; Student[] students = new Student[ MAX_COUNT]; //管理するStudent、ここに int studentCount =0; //配列に格納されたStudentの数 //・引数 :student /Student 追加する Student //・戻り値:追加できた時は true, 失敗したときはfalse を返す. //・目的 :StudentInfo 内の配列に Student を追加する.引数の値が null である場合, // 配列で扱 える最大数を超えた場合や,既に同じ情報を持つ Student が登録されている場合は, // 登録されずにfalse を返す. public boolean addStudents(Student student){ System.out.println("0studentCount開始"+studentCount); if(studentCount==0){ students[studentCount] = student; studentCount++; System.out.println("1"+students[0].getname());//チェック1 System.out.println("1"+students[0].getage()); System.out.println("1"+students[0].getid()); System.out.println("1studentCount開始"+studentCount); }else{ System.out.println("2"+student.getname());//チェック2 System.out.println("2"+student.getage()); System.out.println("2"+student.getid()); System.out.println("2studentCount開始"+studentCount); } //引数にStudent以外のクラスが指定 された時はfalseを返す if(student instanceof Student != true ){ System.out.println("3if(student instanceof Student != true )"); //チェック3 return false; } System.out.println("4if(student instanceof Student != true )抜けた"); //チェック4 //配列で扱える最大数を超えた場合 if(studentCount > MAX_COUNT || student == null){ System.out.println("5if(studentCount > MAX_COUNT || student == null)"); //チェック5 return false; } System.out.println("6if(studentCount > MAX_COUNT || student == null)抜けた"); //チェック6 //配列の要素を一つ一つ同じである かどうかを確認し,全て同じであれ ばtrueを返す //for文で重複チェック for(int i=0; i<=studentCount; i++){ //if(student.getname().equals(students[i].getname()) && student.getid().equals(students[i].getid()) && student.getage() == students[i].getage()){ if(student.equals(students[i])){ return true; } } students[studentCount] = student;//student[studentCount]にstudentを代入 studentCount++; System.out.println("7-1"+student.getname()); //チェック7-1 System.out.println("7-2"+students[0].getname()); //チェック7-2 System.out.println("8studentCount一周終わり"+studentCount); //チェック8 return false; } //・引数 :なし //・戻り値:配列に登録されている Studentの平均値 //・目的 :StudentInfo の配列に登録されている Student の平均年齢を算出して返す. // 登録され ている Student がない場合は0 を返す. public double getAverage() { double average = 0.0; for (int i = 0; i < this.studentCount; i++) average += (double) this.students[i].getage(); //System.out.println( average += (double) this.students[i].getage()); //チェック9 System.out.println("9平均"+average / this.studentCount); //チェック return average / this.studentCount; }

}

import static org.junit.Assert.*;

import org.junit.Test;

public class StudentInfoTest {

@Test public void testAddStudents() { StudentInfo stu = new StudentInfo(); stu.addStudents(new Student("Taizo Hayashi","113",23)); stu.addStudents(new Student("Hikari Watanabe","114",21)); stu.addStudents(new Student("Hikari Watanabe","114",21)); stu.addStudents(new Student("Taro Sato","111",23)); stu.addStudents(new Student("Akari Kato","112",22)); double average = StudentInfo.getAverage(); assertEquals(22.00, average, 0.0); }

}

students[0].getname()や.getage()であれば要素を取り出せるのですが、students[studenCount].getname()やstudents[i].getname()だと要素を取り出せません。
また、students[studenCount]=studentとした場合はnullになるのですが、students[0]=studentとした場合は中身があり、getname()や.getage()であれば要素を取り出せます。
iやstudentCountはループで回したりカウントアップしているのに0などの数字と何か違いがあるのでしょうか。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/07/12 20:56

とりあえず マークダウン位おぼえよう。 使い方はツアーやらヘルプやらあるんだからそっちみてね
guest

回答2

0

ベストアンサー

thisはそのクラス(もしくはインスタンス)そのものを表すキーワードです。
この場合StudentInfoTest.testAddStudents()の中で宣言されているStudentInfo stuを指しています。
ですので比較している各データは StudentInfo クラスの冒頭で宣言されている this.name="" , this.ID="" ,this.age =0 となります。

そこを本来比較するべきデータに変更すれば良いです。

投稿2020/07/12 13:03

Kaleidoscope

総合スコア257

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

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

TaWa

2020/07/12 14:27

早速のご返答ありがとうございます。 this.name="" , this.ID="" ,this.age =0について、与えた配列を順にセットするのは調べないとできないので、重複のチェックができるか確認するために、初期値を配列と重複する内容にして確認しました。結果として重複のチェックはできていませんでした。コンソールに中身を表示して見て確認したところ、target.idだけがなぜかすべてnullとなっていました。target.nameとtarget.ageは中身が入っています。
swordone

2020/07/12 16:57 編集

> 与えた配列を順にセットするのは調べないとできないので、重複のチェックができるか確認するために、初期値を配列と重複する内容にして確認しました。 これどういう意味ですか?何度読み返しても意味が分かりません。 「与えた配列」「初期値」「配列と重複する内容」がまずわかりませんし、「順にセットするのは調べないとできない」も何のことか理解できません。
Kaleidoscope

2020/07/12 23:49 編集

まずはそのif文で「何」と「何」を比較する必要があるのか考えてください。 一方は登録する予定のStudent クラスのインスタンスです。具体的には addStudent 関数に引数として渡された変数 student です。(今回の場合は更に変数targetに代入されて使用されている。) ではそれを「何」と比較する必要がありますか?
TaWa

2020/07/14 16:15

比較を行いたいのは、比較後に登録された配列students[i]と、新しく登録しようとしてる配列StudentInfoTestに準備した配列(現状stuとされているもの)です。
Kaleidoscope

2020/07/15 10:39

コードは上から順に読んでいきましょう。 //重複チェック となっている箇所では、これから登録しようとしている変数studentはまだ配列studentsには登録されていません。 その下の //student[studentCount]にstudentを代入 のところで初めて登録されます。 (重複チェックをしてから登録しようとしてるのだから当然です。) また、"stu"は「StudentInfoTestに準備した配列」ではなく、StudentInfoクラスの実体です。(インスタンスと呼びます) 強いて言うなら stu.students が準備した配列であり、StudentInfoクラスから見たら配列studentsそのものです。 答えは関数の説明に書いてあるとおり、 「StudentInfo 内の配列(students)に Student(student) を追加する.」のだから、 引数で受け取ったstudentと配列studentsの各要素を比較すればいいのです。 今まで登録されたデータはstudents[0]からstudents[studentCount]までに格納されているので for文でそれぞれ比較していけば良い。
TaWa

2020/07/16 14:42

ありがとうございます。少し前進しましたが、2つの問題が解決できません。 ①java.lang.NullPointerException students[i].getname()やsutudent[studentCount].getname()を行い、要素を取り出そうとするとjava.lang.NullPointerExceptionが出てしまいます。 students[0].getname()であれば、何も出ないのです。iやstudensCountもカウントアップしているのに、0などの数字は何か異なるのでしょうか。 ②students[studentCount]=studentがnullになる student[0]=studentであれば、nullにならずgetname()などで要素を取り出せるのですが、students[studentCount]=studentの場合はnullになってしまいます。
Kaleidoscope

2020/07/16 14:53

おそらく初期化されていないインスタンスや配列の要素にアクセスしています。 students[studentCount]は重複チェックが終わったあとに代入するだけなので、students[studentCount].getname()が行われるはずはありません。
guest

0

//配列の要素を一つ一つ同じである かどうかを確認し,全て同じであれ ばtrueを返す

おそらく、StudentInfoの中になる以下の部分の記載が間違っているのではないかとは考えているのですが、どう直したらいいのかわかりません。
for(int i=0; i<=studentCount; i++){
if(this.name.equals(target.name) && (this.id.equals(target.id)) && this.age == target.age)
return false;
}

thisは、配列の要素じゃありません。
同じ比較(thisとtarget)をstudenCount回繰り返しても意味がありません
※ループするたびに、比較対象が変わらないので

thisでなく配列の要素と比較してください。

配列の名前(変数名)は、なんですか?
配列から要素を取得して(forループ)みてください。

投稿2020/07/13 03:54

momon-ga

総合スコア4820

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問