作っているプログラム
5人の生徒がいて、1人目から順に「○番目のテストの順位は□位です」と表示するプログラムを書いています。テストの点数は、Integer型の配列変数に格納しており、その配列のコピーを降順でソートしたものと比較して順位を出しています。
クラス型配列同士の値の比較方法について確認したいことがありますので宜しくお願い致します。
コードの全体
これがコードの全体です。
問題は下部にあるネストされたfor文の中の、if文の条件です。
詳細は該当のソースコードをご覧ください。
java
1import java.util.Arrays; 2import java.util.Collections; 3 4class renshu19 5{ 6 public static void main(String[] args) { 7 8 Integer[] score = {70, 50, 80, 60, 100}; //左から1人目~5人目 9 //Integer(クラス型)型の配列 10 11 Integer[] scoreCopy; 12 scoreCopy = new Integer[5]; 13 //配列scoreをコピーする為の配列 14 15 System.arraycopy(score,0,scoreCopy,0,score.length); 16 //値コピー 17 18 Arrays.sort(scoreCopy,Collections.reverseOrder()); 19 //コピーした配列を降順でソートする 20 21 for(int i = 0; i < score.length; i++){ 22 for(int j = 0; j < score.length; j++){ 23 if(score[i].equals(scoreCopy[j])){ //クラス型の配列の値の比較はこれ一択? 24 //score[i] == scoreCopy[j] これも成功 25 System.out.println((i+1) + "人目の順位は" + (j+1) + "位です。"); 26 } 27 } 28 } 29 } 30}
該当のソースコード・疑問点
クラス型配列同士の比較なので、ルール通りに行うと score[i].equals(scoreCopy[j]) での比較になると思うのですが、初め、私はコメントのように score[i] == scoreCopy[j] としてしまったのですが、これでも成功しました。 何故でしょう、このように行うことは良くないでしょうか。ルール外になりますか。
java
1 if(score[i].equals(scoreCopy[j])){ //オブジェクト型の配列の値の比較はこれ一択? 2 //score[i] == scoreCopy[j] これでも成功 3 System.out.println((i+1) + "人目の順位は" + (j+1) + "位です。"); 4 }
【追記】皆さんのご回答をもとに、少し調べた内容
まずここまで、==で比較すると、インスタンスの比較になると理解しました。
System.arraycopyでは中身をコピーしたが、Integer型の配列なので、値が格納されているメモリの場所をコピーしている事になって、結果としてコピーしたものはコピー元と同じオブジェクトを指しているという事。
そして、momon-ga様が二つ目に示して頂いたコードの中のように、intでキャストして比較ができるという事。
ただ、疑問に思った事。
momon-ga様が最初に示して頂いたコードの、下から2行目の結果がfalseになる事が疑問でした。
System.out.println(bg1.equals(bg2)); //false
System.out.println(bg1.compareTo(bg2) == 0); //true
これについて調べていった結果、equalsメソッドは、BigDecimalクラスでオーバーライドされていて、
(Integerクラスや、Stringクラスでもされていました。他にもあるかもしれません)
以下のように記述されており、上から三つ目のifのところが該当の箇所だと思われます。
スケール値が違うとfalseを返すというような。
java
1 @Override 2 public boolean equals(Object x) { 3 if (!(x instanceof BigDecimal)) 4 return false; 5 BigDecimal xDec = (BigDecimal) x; 6 if (x == this) 7 return true; 8 if (scale != xDec.scale) 9 return false; 10 long s = this.intCompact; 11 long xs = xDec.intCompact; 12 if (s != INFLATED) { 13 if (xs == INFLATED) 14 xs = compactValFor(xDec.intVal); 15 return xs == s; 16 } else if (xs != INFLATED) 17 return xs == compactValFor(this.intVal); 18 19 return this.inflated().equals(xDec.inflated()); 20 } 21
Integerクラスも確認したところ、オブジェクト同士の確認もするが
Integerクラス同士のオブジェクトの比較の際には、中の値を比べてくれるコードが記述されていました。
なので、Integerクラスにおいて、オブジェクト同士が同値であるかどうか確認したい場合は
(Integerクラス内でオーバーライドした)equalsメソッドを使う、で大丈夫だと思いました。
長々と申し訳ありません。皆様ありがとうございました。
回答4件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/15 05:40