これらでいっぱいの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
List.contains(...)
メソッドは、equals(Object)
を使用して、引数オブジェクトがリストに「含まれる」かどうかを決定するように定義されています。したがって、equals
...をオーバーライドする必要があります。デフォルトの実装が必要なものでないと仮定します。
ただし、List.contains(...)
はリスト内のすべての要素に対して引数をテストする可能性があることに注意する必要があります。長いリストの場合、それは高価です。アプリケーションの詳細に応じて、別のコレクションタイプ(例:HashSet
、TreeSet
またはLinkedHashSet
)の代わりにList
を使用します。これらのいずれかを使用する場合、クラスはhashCode
をオーバーライドするかComparable
を実装するか、選択した内容に応じて別のComparator
...を作成する必要があります。 。
(OPが関心を持っているため、代替案についてもう少しアドバイス)
contains
やList
のようなArrayList
タイプでのLinkedList
のパフォーマンスはO(N)
です。 contains
呼び出しの最悪の場合のコストは、リストの長さに正比例します。
TreeSet
の場合、contains
の最悪の場合のパフォーマンスはlog2(N)
に比例します。
HashSet
またはLinkedHashSet
の場合、contains
の平均パフォーマンスは定数であり、コレクションのサイズとは無関係ですが、最悪の場合のパフォーマンスはO(N)
。 (最悪の場合のパフォーマンスは、1)すべてを少数の値にハッシュする貧弱なhashcode()
関数を実装するか、2)「負荷係数」パラメーターを微調整して、ハッシュテーブルが自動的にサイズ変更されないようにします成長するにつれて)
Set
クラスを使用することの欠点は次のとおりです。
get(pos)
メソッドはありません。Set
クラスは、挿入順序を保持しません。使用するコレクションクラスを決定するときは、これらの問題を考慮する必要があります。
おそらくhashCode()を実装する必要があります。一般に、とにかく等号をオーバーライドするときは、常にこれを行う必要があります。
collections docs から:
この仕様は、null以外の引数oを指定してCollection.containsを呼び出すと、任意の要素eに対してo.equals(e)が呼び出されることを意味するものと解釈してはなりません。実装は、最適化を自由に実装できます。これにより、たとえば最初に2つの要素のハッシュコードを比較することにより、equalsの呼び出しが回避されます。 (Object.hashCode()仕様は、等しくないハッシュコードを持つ2つのオブジェクトが等しくなることを保証します。)より一般的には、さまざまなCollections Frameworkインターフェースの実装は、実装者が適切であると見なす場合は常に、基礎となるObjectメソッドの指定された動作を自由に利用できます。 。