20

私はこれらでいっぱいのArrayListを持っています:

class TransitionState {

    Position positionA;
    Position positionB;

    int counter;

    public boolean equals (Object o){

        if (o instanceof TransitionState){

          TransitionState transitionState= (TransitionState)o;

          if ((this.positionA.equals(transitionState.positionA))
                  &&(this.positionB.equals(transitionState.positionB)))
          {
              return true;
          }
        }
     return false;

    }

    @Override
    public String toString() {

        String output = "Position A " + positionA.i+ " "+ positionA.j + " "+ positionA.orientation + " "+
                "Position B " + positionB.i + " "+ positionB.j + " "+ positionB.orientation;

        return output;
    }

}

class Position {

    int i;
    int j;
    char orientation;

    Position() {

    }


    void setIJ(int i, int j){
        this.i=i;
        this.j=j;
    }

    void setOrientation(char c){

        orientation = c;
    }

   public boolean equals(Object o){

        if(o instanceof Position){

          Position p = (Position)o;
          if((p.i==this.i)&&(p.j==this.j)&&(p.orientation==this.orientation))
          {
              return true;
          }
              else return false;

        }

            return false;
   }

} //end class Position

私はこれでそれを照会します:

 if(!transitionStatesArray.contains(newTransitionState)){  //if the transition state is new add and enqueue new robot positions

                 transitionStatesArray.add(newTransitionState); //marks as visited

自分の中に重複する要素が見つかりtransitionStatesArrayました。これはなぜですか?

これらのi、jと方向の値を使用して、マトリックス内の一意の値を埋めていますが、ここに重複があります。

 S  .  N 
 *  *  * 
 .  D  D 


 E  .  O 
 *  *  * 
 .  D  D 


 N  .  S 
 *  *  * 
 .  D  D 


 S  .  N 
 *  *  * 
 .  D  D 
4

2 に答える 2

31

このメソッドは、引数オブジェクトがリストに「含まれている」かどうかを判断するList.contains(...)ために使用するように定義されています。equals(Object)したがって、オーバーライドする必要がありますequals...デフォルトの実装が必要なものではないと仮定します。

List.contains(...)ただし、リスト内のすべての要素に対して引数をテストする可能性があることに注意する必要があります。長いリストの場合、それは高価です。アプリケーションの詳細によってHashSet、. これらのいずれかを使用する場合、選択した内容に応じて、クラスで をオーバーライドまたは実装するか、別のものを作成する必要があります。TreeSetLinkedHashSetListhashCodeComparableComparator


(代替案についてもう少しアドバイス... OPが興味を持っているので)

orのようcontainsList型の のパフォーマンスは です。呼び出しの最悪の場合のコストは、リストの長さに正比例します。ArrayListLinkedListO(N)contains

TreeSet最悪の場合のパフォーマンスcontainsは に比例しlog2(N)ます。

HashSetまたはの場合、コレクションのサイズに関係なく、LinkedHashSetの平均パフォーマンスは一定ですが、最悪の場合のパフォーマンスはです。(最悪の場合のパフォーマンスは、1)すべてを少数の値にハッシュする貧弱な関数を実装するか、2) 「負荷係数」パラメーターを微調整して、ハッシュ テーブルが大きくなるにつれて自動的にサイズ変更されないようにする場合に発生します。)containsO(N)hashcode()

Setクラスを使用することの欠点は次のとおりです。

  • それらはセットです。つまり、2 つ以上の「等しい」オブジェクトをコレクションに入れることはできません。
  • それらは索引付けできません。たとえば、get(pos)メソッドはありません。
  • 一部のSetクラスは、挿入順序さえ保持しません。

これらの問題は、使用するコレクション クラスを決定する際に考慮する必要があります。

于 2011-05-06T05:51:16.667 に答える
1

おそらく hashCode() を実装する必要があります。一般に、equals をオーバーライドするときは常にこれを行う必要があります。

コレクションのドキュメントから:

この仕様は、Collection.contains を null 以外の引数 o で呼び出すと、任意の要素 e に対して o.equals(e) が呼び出されることを意味すると解釈されるべきではありません。実装では、たとえば最初に 2 つの要素のハッシュ コードを比較するなどして、equals 呼び出しを回避する最適化を自由に実装できます。(Object.hashCode() 仕様は、ハッシュ コードが等しくない 2 つのオブジェクトが等しくないことを保証します。) より一般的には、さまざまな Collections Framework インターフェイスの実装は、実装者が適切と考える場合はいつでも、基になる Object メソッドの指定された動作を自由に利用できます。 .

于 2011-05-06T05:49:13.893 に答える