ewuals(myclass)、ewuals(int)とhash()を実装した、自分で作成したクラスがあります。
そのクラスをVectorに格納して、indexOf()やlastIndeOf()で検索しようとしていますが、-1が返されます。
for()ループとequals()を使用して自分で検索すると、意図した値が帰ってくるのですが。どこがいけないのでしょうか?
===>java -version
java version "1.6.0_11"
Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)
importjava.util.Vector;
===>type equaltest.java
class equaltest {
public static void main(String args[]) {
myclassmyc[]=newmyclass[8];
myc[0]=newmyclass(false,10,3);
myc[1]=newmyclass(false,10,4);
myc[2]=newmyclass(false,20,3);
myc[3]=newmyclass(false,20,4);
myc[4]=newmyclass(true,10,3);
myc[5]=newmyclass(true,10,4);
myc[6]=newmyclass(true,20,3);
myc[7]=newmyclass(true,20,4);
//Vectorに追加
Vector<myclass>myVec=newVector<myclass>();
for (intlp1=0;lp1<myc.length;lp1++){
myVec.add(myc[lp1]);
}
//Vectorの中身を表示
System.out.println(myVec.toString());
System.out.println("------------");
System.out.println("Vector.indexOfの返す値は・・・");
System.out.println("10\t:"+myVec.indexOf(10));
System.out.println("20\t:"+myVec.indexOf(20));
System.out.println("3\t:"+myVec.indexOf(3));
System.out.println("4\t:"+myVec.indexOf(4));
myclassmytmp=newmyclass(true,20,4);
//mytmpの中身を表示
System.out.println(mytmp.toString());
System.out.println("mytmp\t:"+myVec.indexOf(mytmp));
System.out.println("自分でequals比較すると・・・");
System.out.println("mytmp?2\t:"+mytmp.equals(myc[2]));
System.out.println("mytmp?3\t:"+mytmp.equals(myc[3]));
System.out.println("mytmp?4\t:"+mytmp.equals(myc[4]));
System.out.println("mytmp(10):"+mytmp.equals(10));
System.out.println("mytmp(20):"+mytmp.equals(20));
System.out.print("自分でVectorを検索すると・・・[");
for (intlp1=0;lp1<=myVec.size();lp1++){
if(lp1==myVec.size()){
System.out.println("-1(not found)]");
break;
}
if(mytmp.equals((myclass)(myVec.elementAt(lp1)))==true){
System.out.println(""+lp1+"]");
break;
}
}
}
}
===>type myclass.java
publicclass myclass{
booleanflg;
intvalurT;
intvalurF;
//
myclass(){
flg=false;
valurT=20;
valurF=5;
}
myclass(booleanaf,intavalurT,intavalurF){
flg=af;
valurT=avalurT;
valurF=avalurF;
}
//
publicbooleanequals(intmyArg){
if(flg){
return(valurT==myArg);
}else{
return(valurF==myArg);
}
}
//
publicbooleanequals(myclassargmycls){
if(flg){
return(valurT==argmycls.valurT);
}else{
return(valurF==argmycls.valurF);
}
}
publicStringtoString(){
return"[flg:"+flg+" valurT:"+valurT+" valurF:"+valurF+"]";
}
public int hashCode(){
if(flg){
return(valurT);
}else{
return(valurF);
}
}
}
No.1
- 回答日時:
VectorのindexOfの使い方がおかしいから。
Vector配列にint型の値は入ってないから-1が返却されるのは当たり前です。
System.out.println("10\t:"+myVec.indexOf(10));
この回答への補足
>Vector配列にint型の値は入ってないから....
Integer.equals(Vector配列の(k)番目)、つまりindexOfの引数.equals(Vector配列のelementAt(k))という判断をしている、という理解でよろしいでしょうか。
それにしても、こちらでも(同じクラスを使っていても)-1が返されるのがわかりません。
System.out.println("mytmp\t:"+myVec.indexOf(mytmp));
No.2ベストアンサー
- 回答日時:
適切な関数がオーバーライドされていないためです。
Vector などのコレクションでは同じかどうかの比較に equals(Object)
を使用します。
そのため、equals(int), equals(myclass) などのような独自関数を
定義してもコレクション内部では使用されません。
例えば、サンプルコードのように indexOf() に int を入れても位置を
取得したいときには、myclass に以下の関数を定義する必要があります。
boolean equals(Object obj) {
if(obj instanceof Integer) {
int i = ((Integer)obj).intValue();
if(flg){
return (valurT == i);
}else{
return (valurF == i);
}
}
return super.equals(obj);
}
このように、引数の Object が Integer かどうかを判断して適切に
場合分けをする equals(Object) を実装しておかなくてはいけません。
Vector.indexOf() に myclass を入れる場合も、同様に equals(Object) を改良する必要があります。
ありがとうございました。equals(Object) を改良する必要があります、というのは予想外でした。
以下の関数を追加して実装したら、myclass 同士の比較はうまくいくようになりました。
publicboolean equals(Object obj) {
if(obj instanceof Integer) {
int i = ((Integer)obj).intValue();
return(this.equals(i));
}else if(obj instanceof myclass) {
myclass myc = ((myclass)obj);
return(this.equals(myc));
}
return super.equals(obj);
}
No.3
- 回答日時:
NO1です。
>Integer.equals(Vector配列の(k)番目)、つまりindexOfの引数.equals(Vector配列のelementAt(k))という判断をしている、という理解でよろしいでしょうか。
そうですね。つまりこの場合はObjectのequalsメソッドで判定しているってことです。
>それにしても、こちらでも(同じクラスを使っていても)-1が返されるのがわかりません。
これについてはすでにNo2さんが回答している通り、メソッド(equals(Object))のオーバライドが足らないだけです。
ただ、equalsメソッドは完全一致だとほとんどの人は思うと思いますが、myclassだとフラグ分けしているので完全一致でなくても良いように見えますが、いいんですかね?
ま、これは仕様の話ですか。
なるほど、ということはIntegerで渡してしまうと
myClassをオーバライドしても無駄、ということになりますね。
別のやり方を考えます。
>equalsメソッドは完全一致だと・・・
ええ、確かに普通は完全一致なのですが。こういうことを実現したくていろいろやっている最中でして。
1.表裏が区別できるカードに数字が書いてあります。
2.山札のカードは表裏ごっちゃになっている状態です。
3.表向きのカードが指示されたときには、山札から、「表向きになっていて表面に書いてある数字が一致する」カード(裏はどうでもよい)を、裏向きのカードが指示されたときには、山札から、「裏向きになっていて裏面に書いてある数字が一致する」カード(表はどうでもよい)を、探します。
#フラグの比較もつけてみたけれど思ったとおりには動かない^^;
No.4
- 回答日時:
すいません。
前回の回答に一部間違いがありました。コレクション内部で equals(Object) が呼び出されるのは正しいのですが、ww-_-ww さんの回答にありますように indexOf() で呼び出されるのは、「<引数>.equals(<要素>)」です。
myclass の方でうまくいったのは、indexOf() の引数として渡される myclass が適切に equals(Object) をオーバーライドしていたためです。
一方、int の場合には indexOf() に実際に渡されるのは Integer クラスとなりますが、こちらは myclass に対する適切な処理が施されている equals(Object) を持っていません。
このため、myclass ではうまくいくが、int ではうまくいかないということになってしまっています。
int を指定して要素を取り出すときには、int をラップして equals(Object) をオーバーライドしたラッパーオブジェクトを引数として渡す必要があります。例としては以下の様なクラスです。
// クラス定義
class IntHolder {
int fInt;
public IntHolder(int i) {
fInt = i;
}
public equals(Object obj) {
if (obj instanceof myclass) {
myclass my = (myclass)obj;
return my.equals(fInt);
}
return super.equals(obj);
}
}
// 使用方法
int pos = myVec.indexOf(new IntHolder(10));
ありがとうございます。こちらも、無事、動きました。
後で見る人のために一応補足しておきます。
class IntHolder は、publicでなくてよいので独立したクラスにしましょう。
class IntHolder を class equaltest の内部クラスにするとコンパイルが通りません。(「static でない 変数 this を static コンテキストから参照することはできません。」となります。)
public boolean equals(Object obj) {
でした。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Ruby vscode 文字化け 1 2022/05/21 19:17
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- PHP PHPの構文で間違えが分からない 5 2022/07/11 16:38
- 英語 この英文の意味を教えてください 3 2023/07/07 20:36
- PHP SQLとPHPの連結方法がわからないのでアドバイスお願い致します 1 2022/07/12 12:16
- Visual Basic(VBA) InputBoxでキャンセルボタンを押したらファイル自体を閉じたい 3 2022/07/23 17:52
- Java java 引数 戻り値のあるメソッド 3 2023/02/12 06:23
- PHP アコーディオンPHPが上手くいかない 3 2022/07/15 16:29
- ボランティア ウクライナ人からどういうこと? 6 2022/03/28 07:37
- 英語 『G19 Gen5 MOS - Modular Optic System for Gen5』 の 『 1 2023/03/05 13:37
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語のポインターに関する警告
-
NaNではなく、0と表示させたい
-
Javaのコマンドライン引数を使...
-
java シンボルが見つかりません...
-
EclipseでJava
-
Webアプリケーション checkbox...
-
Javaのプログラムがどうしても...
-
コマンドプロンプトに不正な文...
-
応用情報技術者試験の令和元年...
-
パソコンキーボードで時分秒を...
-
VBAで配列の計算
-
JavaScriptでcgiの戻り値を受け...
-
ダブルクォーテーションのrepla...
-
byte配列→float型の値を読みlon...
-
SAStrutsでActionからJSPに値を...
-
javaの初歩的な質問です。
-
大量のデータを読み込んで表示...
-
バイト配列からfloat型の数値を...
-
読み込み回数
-
servlet のbackground
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のポインターに関する警告
-
[JAVA]try 内の変数を外で!?
-
JSPやサーブレットでSystem.out...
-
JAVAのDouble型の小数点以下の...
-
EclipseでJava
-
「続行するには何かキーを押し...
-
文字列の引き算
-
java シンボルが見つかりません...
-
JAVA 文字色変更
-
改行の判定方法
-
JAVAのエラーの意味が分かりま...
-
Javaのコマンドライン引数を使...
-
java教えてください。
-
曜日の取得方法を教えて下さい!
-
JavaにはなぜGO TO ...
-
Javaでカレントディレクトリを...
-
構文解析中にファイルの終わり...
-
JAVA 三角形の判定
-
複数行キーボード入力した後に...
-
printfの%fにおいて教本どおり...
おすすめ情報