5

次のように定義さFooれた、特定の にオブジェクトを格納するラッパーを含む TreeSet があります。position

class Wrapper implements Comparable<Wrapper> {
  private final Foo foo;
  private final Double position;

  ...

  @Override boolean equals(Object o) {

    ... 

    if(o instanceof Wrapper)
        return o.getFoo().equals(this.foo);

    if(o instanceof Foo)
        return o.equals(this.foo);
  }

  @Override public int compareTo(MarkerWithPosition o) {
      return position.compareTo(o.getPosition());
  }
}

NavigableSet<Wrapper> fooWrappers = new TreeSet<Wrapper>();

TreeSetで注文したいのですpositionが、で検索できるようにしたいからですfoo。しかし、これらの操作を実行すると:

Foo foo = new Foo(bar);
Wrapper fooWrapper = new Wrapper(foo, 1.0);
fooWrappers.add(fooWrapper);

fooWrapper.equals(new Wrapper(new Foo(bar), 1.0));
fooWrapper.equals(new Foo(bar));
fooWrappers.contains(fooWrapper);
fooWrappers.contains(new Wrapper(foo, 1.0));
fooWrappers.contains(new Wrapper(new Foo(bar), 1.0));
fooWrappers.contains(new Wrapper(foo, 2.0));
fooWrappers.contains(foo);

私は得る:

true
true
true
true
true
false
Exception in thread "main" java.lang.ClassCastException: org.gridqtl.Marker cannot be cast to java.lang.Comparable
    at java.util.TreeMap.getEntry(TreeMap.java:325)
    at java.util.TreeMap.containsKey(TreeMap.java:209)
    at java.util.TreeSet.contains(TreeSet.java:217)

それらがすべて返されることを期待しているとき、APIが示唆するように私のメソッドを使用していないtrueようです。上書きする必要がある別の方法はありますか?TreeSet.containsequals

4

2 に答える 2

10

TreeSet は、 javadoc - 強調鉱山compareToで説明されているように、実際に使用する Set 実装です。

Set インタフェースを正しく実装するためには、(明示的なコンパレータが提供されているかどうかに関係なく) セットによって維持される順序付けが equals と一致している必要があることに注意してください。(equals との整合性の正確な定義については、Comparable または Comparator を参照してください。) これは、Set インターフェイスが equals 操作に関して定義されているためですが、TreeSet インスタンスはその compareTo (または比較) メソッドを使用してすべての要素の比較を実行するため、2 つのこのメソッドによって等しいと見なされる要素は、セットの観点からは equalです。セットの動作は、その順序付けが equals と一致しない場合でも明確に定義されています。Set インターフェースの一般的な契約に従わないだけです。

于 2012-07-30T13:17:39.143 に答える
0

TreeSet は順序付きセットです。

equals注文情報を提​​供できないため、TreeSet は別のものを使用する必要があります。

この「何か他のもの」はComparableインターフェース、またはそのいとこのComparatorインターフェースです。

どちらのインターフェースも、クラスの 2 つのオブジェクトを順序付ける方法に関する情報を提供します。

于 2012-07-30T13:19:05.977 に答える