• ベストアンサー

独自クラスをVectorに格納してindexOfで検索する方法

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) import java.util.Vector; ===>type equaltest.java class equaltest { public static void main(String args[]) { myclass myc[] = new myclass[8]; myc[0] = new myclass(false, 10 , 3); myc[1] = new myclass(false, 10 , 4); myc[2] = new myclass(false, 20 , 3); myc[3] = new myclass(false, 20 , 4); myc[4] = new myclass(true, 10 , 3); myc[5] = new myclass(true, 10 , 4); myc[6] = new myclass(true, 20 , 3); myc[7] = new myclass(true, 20 , 4); //Vectorに追加 Vector<myclass> myVec = new Vector<myclass>(); for (int lp1 = 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)); myclass mytmp = new myclass(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 (int lp1 = 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 public class myclass{ boolean flg; int valurT; int valurF; // myclass(){ flg = false; valurT = 20; valurF = 5; } myclass(boolean af, int avalurT, int avalurF){ flg = af; valurT = avalurT; valurF = avalurF; } // public boolean equals(int myArg){ if(flg){ return (valurT == myArg); }else{ return (valurF == myArg); } } // public boolean equals(myclass argmycls){ if(flg){ return (valurT == argmycls.valurT); }else{ return (valurF == argmycls.valurF); } } public String toString(){ return "[flg:"+flg+" valurT:"+valurT+" valurF:"+valurF+"]"; } public int hashCode(){ if(flg){ return (valurT); }else{ return (valurF); } } }

  • Java
  • 回答数4
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • azumaiya
  • ベストアンサー率100% (5/5)
回答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) を改良する必要があります。

osu_neko09
質問者

お礼

ありがとうございました。equals(Object) を改良する必要があります、というのは予想外でした。 以下の関数を追加して実装したら、myclass 同士の比較はうまくいくようになりました。 public boolean 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); }

その他の回答 (3)

  • azumaiya
  • ベストアンサー率100% (5/5)
回答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));

osu_neko09
質問者

お礼

ありがとうございます。こちらも、無事、動きました。 後で見る人のために一応補足しておきます。 class IntHolder は、publicでなくてよいので独立したクラスにしましょう。 class IntHolder を class equaltest の内部クラスにするとコンパイルが通りません。(「static でない 変数 this を static コンテキストから参照することはできません。」となります。) public boolean equals(Object obj) { でした。

  • ww-_-ww
  • ベストアンサー率51% (46/89)
回答No.3

NO1です。 >Integer.equals(Vector配列の(k)番目)、つまりindexOfの引数.equals(Vector配列のelementAt(k))という判断をしている、という理解でよろしいでしょうか。 そうですね。つまりこの場合はObjectのequalsメソッドで判定しているってことです。 >それにしても、こちらでも(同じクラスを使っていても)-1が返されるのがわかりません。 これについてはすでにNo2さんが回答している通り、メソッド(equals(Object))のオーバライドが足らないだけです。 ただ、equalsメソッドは完全一致だとほとんどの人は思うと思いますが、myclassだとフラグ分けしているので完全一致でなくても良いように見えますが、いいんですかね? ま、これは仕様の話ですか。

osu_neko09
質問者

お礼

なるほど、ということはIntegerで渡してしまうと myClassをオーバライドしても無駄、ということになりますね。 別のやり方を考えます。 >equalsメソッドは完全一致だと・・・ ええ、確かに普通は完全一致なのですが。こういうことを実現したくていろいろやっている最中でして。 1.表裏が区別できるカードに数字が書いてあります。 2.山札のカードは表裏ごっちゃになっている状態です。 3.表向きのカードが指示されたときには、山札から、「表向きになっていて表面に書いてある数字が一致する」カード(裏はどうでもよい)を、裏向きのカードが指示されたときには、山札から、「裏向きになっていて裏面に書いてある数字が一致する」カード(表はどうでもよい)を、探します。 #フラグの比較もつけてみたけれど思ったとおりには動かない^^;

  • ww-_-ww
  • ベストアンサー率51% (46/89)
回答No.1

VectorのindexOfの使い方がおかしいから。 Vector配列にint型の値は入ってないから-1が返却されるのは当たり前です。 System.out.println("10\t:"+myVec.indexOf(10));

osu_neko09
質問者

補足

>Vector配列にint型の値は入ってないから.... Integer.equals(Vector配列の(k)番目)、つまりindexOfの引数.equals(Vector配列のelementAt(k))という判断をしている、という理解でよろしいでしょうか。 それにしても、こちらでも(同じクラスを使っていても)-1が返されるのがわかりません。 System.out.println("mytmp\t:"+myVec.indexOf(mytmp));

関連するQ&A

  • Vectorクラスの使い方

    いつもお世話になっております。 Vector vector = new Vector(); String array[] = new String[11]; vector.addElement(array) for( int i = 0; i1 < vector.size(); i++) { String str = (String)vector.get(i); System.out.println(str); } 11の配列にデータ(String)を入力し(ここでは省略)、11すべてをVectorへいれ、String型で取り出したいのですがエラーになります。 System.out.println(vector1.get(i));だと文字化けします。 アドバイスお願いします。そういったことを書いてあるサイト等ご存知でしたらお願いします。

    • ベストアンサー
    • Java
  • boolean を返すクラス(Java)

    JAVAについての質問です。 Java versionは1.6.0_43で、 BlueJ versionは3.0.8です。 これはDriveです↓ Temperature t1 = new Temperature (); Temperature t2 = new Temperature ('F'); t2.setTempObj(32.0); System.out.println ("Does 0C equal 32F: " + t1.equals(t2)); そしてこれがクラス↓ public boolean equals(Temperature testObj) { return //ここにいれるものがなにかわからない。 } アウトプットはtrueです。 booleanのところがdoubleとかなら入れものがわかるのですが、 trueかfalseの場合分けみたいなときはなにを入れたらいいのでしょうか? if文をいれようとも考えましたが結局意味がわからず終いでした。 必要な情報があったら言ってください。 乱文ですが、よろしくおねがいします。

    • ベストアンサー
    • Java
  • booleanの戻り値について

    配列の等価判定をしたいのですが思うように動かないです。 助けてください import java.io.*; class Kadai4 { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int[] TBL1; int[] TBL2; TBL1 = new int[5]; TBL2 = new int[5]; boolean flg=true; System.out.println("配列1を入力"); for (int i = 0; i <= 4; i++) { String s1 = br.readLine(); int t1 = Integer.parseInt(s1); TBL1[i] = t1; } System.out.println("配列2を入力"); for (int i = 0; i <= 4; i++) { String s1 = br.readLine(); int t1 = Integer.parseInt(s1); TBL2[i] = t1; } // 配列表示 System.out.println("配列表示"); for (int i = 0; i < TBL1.length; i++) { System.out.print(" TBL1[" + i + "]=" + TBL1[i]); } System.out.println(""); for (int i = 0; i < TBL2.length; i++) { System.out.print(" TBL2[" + i + "]=" + TBL2[i]); } toka(TBL1, TBL2); System.out.println(""); if (flg == true) { System.out.println("配列は等価"); } else { System.out.println("配列は非等価"); } } private static boolean toka(int[] ss1, int[] ss2) { boolean flg = true; for (int i = 0; i < ss1.length; i++) { if (ss1[i] != ss2[i] || ss1.length != ss2.length) { flg=false } } return flg; } }

  • 複素数の計算するクラスを足せる人がもしいたら

    このJavaプログラムはAdd(足し算)とSud(引き算)を計算するプログラムです。 import Java.io.*; class INT { public int Add(int x,int y){ return x+y; } public int Sub(int x,int y){ return x-y; } } class REAL extends INT { public double Add( double x,double y){ return x+y; } public double Sub( double x,double y){ return x-y; } } class CAL extends REAL { } … public class Cale { public static void main(String args[]) { CAL c = new CAL(); System.out.println( c.Add(1,2) ); System.out.println( c.Add(1.0,2.0)); System.out.println( c.Sub( 1,2)); System.out.println( c.Sub( 1.0,2.0)); } } このプログラムに「複素数の足し算と引き算をするクラス」をクラスの仕様も併せて 作成することが出来る人がもしいたら宜しくおねがいします☆

  • Vectorを用いた問題

    JAVAをはじめたばかりなのですが、以下の問題が分かりません。 Lessonクラス内のaddメソッドにおいてaddした結果が常に学籍番号の小さい順にソートしたいのですが、どうもVectorの使い方がわからず四苦八苦しております。 import java.util.Vector; class main { public static void main(String argv[]){ Lesson l = new Lesson("Kokugo","Tanaka",100); l.add(new Student("00005","Suzuki",100)); l.add(new Student("00002","Sato",64)); l.add(new Student("00003","Ito",43)); l.add(new Student("00007","Endo",92)); l.print(); } } class Lesson { private String name; // 課題名 private String teacher; // 担当者 private int max; // 最大履修者数 private int num; // 登録履修者数 Vector<Student> st; // Student class の配列 public Lesson(String l,String t,int n){ name=l; teacher=t; max=n; num=0; st=new Vector<Student>();// 配列の確保 } public boolean add(Student s){ if(num>=max){ return false;} else { if(num==0){st.insertElementAt(s,num++);} else{ for(int i=0;i<num;i++){ String p=(st.elementAt(i)).id; if(p.compareTo(s.id)>=0){ st.insertElementAt(s,i); } } } return true;} } public void print() { System.out.println("Lesson :"+name); System.out.println("Teacher :"+teacher); System.out.println("students:"+num); for(int i=0;i<num;i++){ st.elementAt(i).print_short(); } System.out.println(); System.out.println("----------"); } } class Student{ public String id; // 学籍番号 private String name; // 名前 private int grade; // 成績 Student(String i,String n, int g){ id=i; name=n; if(g<0)grade=0; else if (g>100) grade=100; else grade=g; } public void print_short() { System.out.println(id+","+name+","+grade); } } 実行結果 Lesson :Kokugo Teacher :Tanaka students:1 00002,Sato,64 ---------- 学籍番号の順にソートしたいのですが、どうやら学籍番号の一番小さいものしか表示されていないようです。どのようにしたらよいのか教えていただけないでしょうか?

    • ベストアンサー
    • Java
  • コンパイルエラーについて。

    今晩は。現在javaについて勉強しているのですが、 コンパイルエラーを解決することが出来ません。 プログラムの内容は好きな文字列を入力し、空白文字を取り除き出力するといったものです。 空白はindexOf()メソッドを使って探し出す。 空白削除はdeleteCharAt()メソッドを使って行う。 というのが条件です。 どなたかご回答おまちしております。 class bf2{ public static void main(String args[])throws IOException{ String t = "end"; String str = ""; int l; int i; int xx=0; String kuhaku = " "; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while(!str.equals(t)){ System.out.print(">"); str = br.readLine(); if(str.equals(t)) break; l = str.length(); i=0; StringBuffer str2 = new StringBuffer(str); while(i<l){ xx = str2.indexOf(kuhaku); str2.deleteCharAt(xx); //こちらがコンパイルエラー会場です。 i++; System.out.println(str2); } } } } Exception in thread "main" java.lang.StringIndexOutOfBoundsException at java.lang.StringBuffer.deleteCharAt(Unknown Source)

    • ベストアンサー
    • Java
  • Pleiades4.4でVectorの使用

    今日は! Javaの初心者です。 Pleiades4.4 LunaのVector機能の使い方について、質問します。 下記は、Pleiades4.3 Keplerに於けるVectorのサンプルプログラムであり、 結果が、コンソールに出力できます(コンパイル、RunはOK)。 このソースをPleiades4.4 Lunaで利用しようとしましたが、コンパイル段階で エラーとなります。 注 変更点) 1)import java.util.Vectorはコメント化しました。 2)vector.addElementは、サポートされていないようです。 Q1)Pleiades4.4 Lunaで走る為の変更について、コメント頂けないでしょうか? Q2)Pleiades4.3 Keplerでは、『import java.util.Vector』に警告が   出ますが、警告が出ないようにする、完全な書き方はありますか? 以上、ご回答頂けますと大変ありがたいです。 //===================================== import java.util.Vector; class Cvector { public static void main(String args[]){ //ベクトルとその要素を作成する Vector vector = new Vector(); vector.addElement(new Integer(995)); vector.addElement(new Float(-14.14f)); vector.addElement(new String("Hello")); vector.addElement(new Long(120000000)); vector.addElement(new Double(-23.45e-11)); //ベクトルの要素を表示 System.out.println(vector); //ベクトル要素を挿入する String s = new String("String_inserted"); vector.insertElementAt(s, 1); System.out.println(vector); //ベクトルから要素を削除する vector.removeElementAt(3); System.out.println(vector); } } //================================

    • ベストアンサー
    • Java
  • Vectorから一部分を取り出す方法はありますか?

    教えていただきたいのですが、 1つのVectorの中に、いろいろなモノ(例えば、番号、名前、年齢のデータなど) が入っていたとして、そのVectorから番号だけ取り出して表示するなどということはできるでしょうか? /* 番号、名前、年齢を取得するメソッド(Vectorが戻り値)があるとして.... */ Vector vec = new Vector() ; str = number+name+age ; //これがたくさんあるとします vec.add(str) ;//番号と名前と年齢の組み合わせをVectorに格納 return vec ; /* 取りだし */ Vector vec=new Vector() ; vec = getVector() ; //メソッドから値を取りだし for(int i=0;i<vec.size();i++) { System.out.println(vec.elementAt(i)) ; } こんな感じだと、全部表示されてしまいます.... 部分ごとに取り出す方法はないでしょうか?初歩的な質問でごめんなさい、 よろしくお願いします!

    • ベストアンサー
    • Java
  • 配列クラスのクラス名

    配列クラスのクラス名 配列クラスのクラス名を教えてください。 配列はクラスですよね。そこまでは分かります。 こんなコードを実行しましたが System.out.println((new int[0]).getClass()); System.out.println((new boolean[0]).getClass()); System.out.println((new String[0]).getClass()); System.out.println((new Integer[0]).getClass()); 親切にこのような結果を出力してくれます。 class [I class [Z class [Ljava.lang.String; class [Ljava.lang.Integer; 結果として配列が何というクラスなのかは分かりません。 (もしかして『[I』『[Z』『[L』という名前のクラスでしょうか?) 昔Javaのソースを読んだときに、配列クラスのファイルも 読んだことがあるような気がするのですが、 なんと言うクラスだったか忘れてしまいました。 パッケージ名+クラス名を教えてください。 よろしくお願いします。

    • ベストアンサー
    • Java
  • java 緊急質問

    java プログラムの課題です このプログラムはファイルを読み込むと最初に十数行の空行が出来てしまいます またファイル内のメールアドレスのみを読み取りたいのですが@の入っていない文も読み取ってしまいます。 あと読み込んだメールアドレスの数だけカウントしたいのですがそこもうまくいっていません。 @を含む一文だけを読み取るようにしたいです。 import java.io.*; public class Email11 { public static void main(String[] argv) throws Exception { String input = "fileContainingEmails.txt"; String output = "copyPasteMyEmails.txt"; BufferedReader cin; cin = new BufferedReader(new InputStreamReader(System.in)); String userInput; System.out.println("Enter input file name [default name: fileContainingEmails.txt]"); userInput = cin.readLine(); if (userInput.equals("")) userInput = input; String name; if (userInput.equals(input)) name = output; else name = userInput; String userOutput; System.out.println("Enter output file name [default name: " + name + " ]"); userOutput = cin.readLine(); if (userOutput.equals("")) userOutput = name; System.out.println("Input FIle : " + userInput); System.out.println("Output FIle : " + userOutput); BufferedReader fin; fin = new BufferedReader(new FileReader(userInput)); String lineFromFile = ""; while (true) { if (!fin.ready()) break; fin.readLine(); lineFromFile = fin.readLine(); System.out.println(lineFromFile.substring(0, lineFromFile.indexOf('@')+1)); PrintWriter fout; fout = new PrintWriter(new FileWriter(userOutput, true)); fout.println(lineFromFile.substring(0, lineFromFile.indexOf('@')+1)); fout.close(); } fin.close(); int count = 0; for (int p = 0; p < lineFromFile.length(); p++) { if (lineFromFile.equals('@')); count++; } if (count == 0) System.out.println("Sorry, no email addresses were found in the file " + userInput); else System.out.println(count + "email addresses were found, and copied to " + userOutput); どのように書き直したらよいのでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう