Javaのequalsメゾットに関する疑問
- Javaのequalsメゾットについて疑問があります。
- オブジェクトの同一性を比較するのか、同値性を比較するのかについて明確にしたいです。
- 複数のサイトで異なる情報を見かけており、どちらが正しいのかわかりません。
- ベストアンサー
JAVAのequalsメゾットに関して
public class Sample{ private int num; public Sample(int num){ this.num=num; public boolean equals(Sample obj){ if(obj==null){ return false; } return this.num==obj.num; } } ここでのequalsメゾットは、object同一性を比較するものか、それともobejectの同値性を比較するものでしょうか? また、オブジェクトクラスの中のequalsメゾットをみたら return(this==obj); と書かれていますが、これを見る限り同一性を比較するものだと思いますが、「objectクラスのequalsメゾットは同値性を比較するメゾット」と書かれているサイトも多くて、一体どっちが正しいでしょうか? ご回答いただければ幸いです。よろしくお願いいたします。 ※OKWAVEより補足:「Webシステム開発」についての質問です。
- arisato1231
- お礼率100% (1/1)
- Java
- 回答数1
- ありがとう数1
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
質問内容のboolean equals(Sample obj)メソッドは確かに同値性を比較するメソッドです。 何故ならあなたがそのように実装したメソッドだからです。 しかし、スーパークラスのboolean equals(Object obj)の処理は"引数が異なるため"上書きされないため、boolean equals(Object obj)は同一性を比較するメソッドとしてそのまま残っています。 したがって、次のようにboolean equals(Object obj)メソッドをオーバーライドして実装すべきかと思います。 public class Sample { private int num; public Sample(int num) { this.num = num; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if ((obj instanceof Sample) == false) { return false; } return this.num == ((Sample) obj).num; } public static void main(String[] args) { Sample s1 = new Sample(1); Sample s2 = new Sample(1); System.out.println(s1.equals(s2)); } } オーバーライドする理由の参考になるかもしれないので、次のコードを載せておきます。 Objectクラスのequalsが実行されます。 public class Sample { private int num; public Sample(int num) { this.num = num; } public boolean equals(Sample obj) { if (obj == null) { return false; } if ((obj instanceof Sample) == false) { return false; } return this.num == obj.num; } public static void main(String[] args) { Sample s1 = new Sample(1); Sample s2 = new Sample(1); System.out.println(s1.equals((Object) s2)); } } Objectクラスで元々実装されているequalsは同一性を比較するメソッドなので、これをオーバーライドして同値性を比較するようにする、というのが定番の流れかな思います。
関連するQ&A
- 整数値を任意のオブジェクトを格納できるスタッククラスに格納する方法
class ObjStack { private Object[] mBuf; private int mSP; public ObjStack(int size) { mSP = 0; mBuf = new Object[size]; } public int getSize() { return mBuf.length; } public int getNum() { return mSP; } public boolean isFull() { return mSP == mBuf.length; } public boolean isEmpty() { return mSP == 0; } public void push(Object x) { if (!isFull()) { mBuf[mSP++] = x; } } public Object top() { Object obj = null; if (!isEmpty()) { obj = mBuf[mSP-1]; } return obj; } public Object pop() { Object obj = null; if (!isEmpty()) { obj = mBuf[--mSP]; } return obj; } } 上のプログラムは任意のオブジェクトを格納できるスタッククラスです。 int型の値はオブジェクトではないので、このObjyStackクラスに格納することができない。 整数値をこのObjStackクラスに格納する方法を教えて下さい。
- ベストアンサー
- Java
- c# Equalsメソッドについて
こんにちは、c#初心者です。 以前まで「Object」型から継承される「Equals」メソッドをオーバーライドするときは public bool override Equals(object obj) { if ( obj is 現在の型 または 任意の親クラスの型 や インターフェイスの型 ) { //判断処理 } else return false; } または、クラス限定で public bool override Equals(object obj) { var temp = obj as 現在の型 または 任意の親クラスの型 や インターフェイスの型; if ( temp != null ) { //判断処理 } else return false; } のようにしていたのですが、「is演算子なんて封印してしまえばいいのに」と仰る方がいらしたので、「is演算子を使わない方がよいのか?」と、「現在のメソッドの形式に不備はないのだろうか?」ということが気になり質問させていただきました。 is演算子を使わないとなると、もう「typeof演算子」を利用する事くらいしか思いつきません。 主に「is演算子」を使っているのは「Equals」メソッドなので、とりあえず「Equal」メソッドだけで。上記メソッドに不備、改善点があればご指摘願います。
- ベストアンサー
- C・C++・C#
- equals()メソッドの継承について
ある本に ーーーーーーーーーーーーーーーーーーーーー class Car { protected int num; protected double gas; public Car() { num = 0; gas = 0.0; System.out.println("車を作成しました。"); } } class Sample8 { public static void main(String[] args) { Car car1 = new Car(); Car car2 = new Car(); Car car3; car3 = car1; boolean bl1 = car1.equals(car2); boolean bl2 = car1.equals(car3); System.out.println("car1とcar2が同じか調べたところ" + bl1 + "でした。"); System.out.println("car1とcar3が同じか調べたところ" + bl2 + "でした。"); } } JavaのクラスはすべてObjectクラスのメンバを継承していますので、equals()メソッドを記述しなくても、このメソッドを呼び出すことが出来るわけです。 ----------------------------------------- JavaのクラスはすべてObjectクラスのメンバを継承していますので、equals()メソッドを記述しなくても、このメソッドを呼び出すことが出来る についてですが、 逆から言えば他の言語の場合は本来クラスの宣言の辺りにでもequals()メソッドを記述する必要があるという意味なんでしょうか?
- ベストアンサー
- Java
- Javaのプログラムの質問です。
Javaのプログラムについての質問です。 Listインターフェースの実装クラスの自作と、作成したクラスの全メソッドを呼び出すサンプルを作成せよ、という問題です。 注意点として、java.util.Listの実装クラスは使用出来ません(ArrayListなど)。実装するメソッドは、コードの中に番号を振ってあります。 import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; import java.util.List; class LocalList implements List{ private int Count; private String Data[]; private Iterator ite; private ListIterator lite; // コンストラクタ void mylist(){ Data = new String[10]; Count = 0; } (1) public boolean add(Object str){ if(Count >= 10){ return false; } Data[Count ++] = new String((String)str); return true; } public void add(int i,Object str){ } public boolean addAll(Collection c){ return false; } public boolean addAll(int i,Collection c){ return false; } (2) public void clear(){ Count = 0; } public boolean contains(Object str){ return false; } public boolean containsAll(Collection c){ return false; } public boolean equals(Object str){ return false; } (3) public Object get(int i){ return (i >= Count); } public int hashCode(){ return -1; } public int indexOf(Object str){ return -1; } public boolean isEmpty(){ return false; } public Iterator iterator(){ return ite; } public int lastIndexOf(Object str){ return -1; } public ListIterator listIterator(){ return lite; } public ListIterator listIterator(int i){ return lite; } (4) public Object remove(int i){ return (i >= Count); } public boolean remove(Object str){ return true; } public boolean removeAll(Collection c){ return false; } public boolean retainAll(Collection c){ return false; } (5) public Object set(int i,Object str){ return Data[i]; } (6) public int size(){ return Count; } public List subList(int i,int j){ return this; } public Object[] toArray(){ return Data; } public Object[] toArray(Object[] a){ return Data; } } class Main { public static void main(String[] args) { mylist sub = new mylist(); sub.add("ビルドバーニングガンダム"); sub.add("ライトニングガンダム"); sub.add("ウイニングガンダム"); sub.add("ガンダムフェニーチェリナーシタ"); sub.add("R・ギャギャ"); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // 改行 System.out.println(); // setメソッド sub.set(1,"ガンダムエピオン"); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // 改行 System.out.println(); // sizeメソッド System.out.println("\r\n" + "機体数は" + sub.size() + "です" + "\r\n"); // removeメソッド sub.remove(1); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // clearメソッド sub.clear(); System.out.println("\r\n" + "機体数が" + sub.size() + "になったので負けです"); } } setメソッドとremoveメソッド以外は起動するのようになったのですが、この2つがうんともすんとも動きません。ジェネリクス型を使うという考え方もあるらしいのですが、ネットで調べてもピンと来ず寸詰まり状態になってしまっています。後少しだと思うのですが。。。。 どなたかご教授頂けないでしょうか?よろしくお願い致します。
- 締切済み
- Java
- nullチェックの書き方(java)
javaでnullチェックをするメソッドがあったとします。 private boolean isNull(Object obj){ // objのnullチェックする } 自分的には private boolean isNull(Object obj){ // objのnullチェックする return obj == null; } と書きたくなってしまうのですが、分かりにくいという指摘をある人からされました。 みなさんでしたら、どのように実装しますか? もしそれによるメリットなんかあったら教えていただきたいです。
- 締切済み
- その他([技術者向] コンピューター)
- Equalsはどこから呼出してるのでしょうか?
wpfの次のpublic override int GetHashCode()とpublic override bool Equals(object obj)とpublic override string ToString()にブレークポイントを設定し「開始」をすると起動時にEqualsで中断、コンボボックスをクリックするとToStringやGetHashCodeで中断しますが、これらの呼び出し元はどこなのでしょうか? 何卒、ご教授よろしくお願いします。 mainwindow.xaml <Grid> <ComboBox x:Name="comboBox" HorizontalAlignment="Left" Margin="200,138,0,0" VerticalAlignment="Top" Width="120" ItemsSource="{x:Static local:classA.comblist}"/> </Grid> mainwindow.xaml.cs public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } class classA { public static classB[] comblist { get { classB[] List = new classB[3]; classB a1 = new classB(); a1.listb = "AAA"; List[0] = a1; classB a2 = new classB(); a2.listb = "BBB"; List[1] = a2; classB a3 = new classB(); a3.listb = "CCC"; List[2] = a3; return List; } } } class classB { private string _listb; public string listb { get { return _listb; } set { _listb = value; } } public override int GetHashCode() { return 1; } public override bool Equals(object obj) { return false; } public override string ToString() { return listb; } } ※長々と書き込みすいません、コード自体に意味はございません
- ベストアンサー
- その他(プログラミング・開発)
- C++の初期化チェックに関する質問です
C++のクラスの初期化済み、未初期化を調べる方法についてご質問させていただきます。 以下のプログラムを実行するとコメント部分//Aで実行時にエラーが発生すると思います。 class Object { int *arg ; public : Object( int len ) { arg = new int[ len ] ; } public : ~Object( ) { delete[ ] arg ; } } ; int main( ) { Object obj1 = Object( 100 ) ; Object *obj2 ; obj1 = *obj2 ; // A return 0 ; } エラー理由はobj2が初期化されていないからだと分かるのですが、 プログラマー側でobj2が初期化されているか調べる方法はあるのでしょうか? 定義時にObject *obj2 = NULL ;としてif文で回避する以外に方法が ありましたら、ぜひご教授願います。
- ベストアンサー
- C・C++・C#
- javaのプログラミングについての質問です。
Javaのプログラムについての質問です。長くなってしまいますがご容赦下さい。 Listインターフェースの実装クラスの自作と、作成したクラスの全メソッドを呼び出すサンプルを作成せよ、という問題です。以下が現在までに作成したコードになります。 注意点として、java.util.Listの実装クラスは使用出来ません(ArrayListなど)。実装するメソッドは、コードの中にコメントを振ってあります。 import java.util.List; import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; class Mylist implements List{ private int Count; private String Data[]; // コンストラクタ public Mylist(){ Data = new String[10]; Count = 0; } /** 実装するaddメソッド @return boolean APIの設定に従う @param e エレメント(要素) **/ public boolean add(E e){ Data[Count] = (String)e; Count++; return true; } public void add(int i,Object str){ } public boolean addAll(Collection c){ return false; } public boolean addAll(int i,Collection c){ return false; } /** 実装するclearメソッド **/ public void clear(){ Count = 0; } public boolean contains(Object str){ return false; } public boolean containsAll(Collection c){ return false; } public boolean equals(Object str){ return false; } /** 実装するgetメソッド @return E エレメント(要素) @param i 指定されたインデックス番号 **/ public E get(int i){ /* エレメントeに、String型Data[i]を キャストして格納*/ E e = (E)Data[i]; return e; } public int hashCode(){ return -1; } public int indexOf(Object str){ return -1; } public boolean isEmpty(){ return false; } public Iterator iterator(){ return null; } public int lastIndexOf(Object str){ return -1; } public ListIterator listIterator(){ return null; } public ListIterator listIterator(int i){ return null; } /** * 実装するremoveメソッド * @return E エレメント(要素) * @param index 指定されたインデックス番号 **/ public E remove(int index){ /* Dataを最大まで回し、iをインクリメントしたData[i++]を String型Dataに格納する*/ for(int i = index; i < Data.length; i++){ Data[i] = Data[index++]; } Count--; E e = (E)Data; return e; } public boolean remove(Object str){ return false; } public boolean removeAll(Collection c){ return false; } public boolean retainAll(Collection c){ return false; } /** * 実装するsetメソッド * @return E エレメント(要素) * @param i 指定されたインデックス番号 * @param element 置き換える要素 **/ public E set(int i,E element){ // String型Dataにelementをキャストして格納 Data[i] = (String)element; // エレメントeにData[i]をキャストして格納 E e = (E)Data[i]; // 値を返す return e; } /** * 実装するsizeメソッド * @return int 指定されたインデックス番号 **/ public int size(){ return Count; } public List subList(int i,int j){ return this; } public Object[] toArray(){ return Data; } public Object[] toArray(Object[] a){ return Data; } } class Main { /** メインメソッド **/ public static void main(String args[]) { Mylist sub = new Mylist(); /* addメソッドを実装し、機体名を要素とする。 addを最大まで回し、getメソッドで要素を取り出して表示する*/ sub.add("ビルドバーニングガンダム"); sub.add("ライトニングガンダム"); sub.add("ウイニングガンダム"); sub.add("ガンダムフェニーチェリナーシタ"); sub.add("R・ギャギャ"); sub.add("ユニコーンガンダム"); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // sizeメソッド System.out.println("\r\n" + "機体数は" + sub.size() + "です" + "\r\n"); // setメソッド sub.set(0,"ガンダムエピオン"); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // 改行 System.out.println(); // removeメソッド sub.remove(1); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // clearメソッド sub.clear(); System.out.println("\r\n" + "機体数が" + sub.size() + "になったので負けです"); } } コンパイルして実行すると、removeメソッドで指定した箇所ではなく、要素の1番最後が削除されています。思うに、removeメソッドを実装する所のfor(int i = index; i < Data.length; i++){の中の条件が違うと思うのですが。。。。 また、現在addには10個箱を作成するようにしていますが、11個目をメインクラス内で用意した場合、例外ではなく新たに箱を作らなければならない、という後だしジャンケン的な事を言われて、思わず「じゃあArrayListでいいじゃないか」と思ってしまいました。 気を取り直してこの3連休で終わらせたいと思っています。ここまでで現状コードの完成は50%かそれ以下だとは思いますが、どなたか上記2点について御教授頂けないでしょうか。よろしくお願い致します。
- 締切済み
- Java
- JAVAのプログラムについて
////////////////////////////////////////////////////////////////// abstract class Time_D { abstract Object Sec(); abstract Object Min(); abstract Object Hour(); } ////////////////////////////////////////////////////////////////// class PresentTime_D extends Time_D { Object Sec() { Date tm = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("s"); return new Integer(Integer.parseInt(formatter.format(tm))); } Object Min() { Date tm = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("m"); return new Integer(Integer.parseInt(formatter.format(tm))); } Object Hour() { Date tm = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("h"); return new Integer(Integer.parseInt(formatter.format(tm))); } } //////////////////////////////////////////////////////////////// class SetTimeCheck_D extends PresentTime_D { int settime; SetTimeCheck_D(int _settime) { settime = _settime; } //-------------------------------------------------- Object Sec() { return new Boolean(((Integer)super.Sec).intValue == settime); } Object Min() { return new Boolean(((Integer)super.Min).intValue == settime); } Object Hour() { return new Boolean(((Integer)super.Hour).intValue == settime); } } 上記のようなプログラムをした場合、下記のようなエラーが出ます。 return new Boolean(((Integer)super.Sec).intValue == settime); } のSecはPresentTime_Dのクラス内のフィールドではありません。 なぜ、このようなエラーが出るのですか?
- 締切済み
- Java
- javaの質問です。合っているかお願いします
間違ってる場合は何が違って何が正解かをお願いします。 よろしくお願いします 1 this.numとnumの違い this.numはインスタンス変数でnumは変数 2 メソッド内のthis.numは何行目で宣言されているか? 4行目 public class Example4 { int num; void plus( int num ) { this.num = this.num + num; } void multiple( int num ) { this.num = this.num * num; } void setNum( int num ) { this.num = num; } int getNum() { return this.num; } }
- ベストアンサー
- Java
お礼
ありがとうございます!