0

一部のオブジェクトを TreeSet (BigHeap クラス内) にプッシュしたいのですが、問題が発生しました:

ここに私のメインクラスがあります:

# --------- Print 3 -----------
Logger.info("items.size() = " + items.size()); 
for (Item item : items) {
  Long score = item.getScoreByQueryItems(queryItems);
  Long itemId = item.id;
  ItemCacheNode node = new ItemCacheNode(itemId,score);
  bigHeap.push(node);  <----- here is the push action ---------
  # --------------Print three times------------
  Logger.info("node.itemId = " + node.getItemId()); 
}
# ---------------Print 1----------
Logger.info("bigHeap.getTreeSet().size() = " + bigHeap.getTreeSet().size()); 

そして、ここに私の BigHeap.java があります:

public class BigHeap<T> {
 private TreeSet<T> treeSet;
 public BigHeap(Comparator<T> comparator){
   this.treeSet = new TreeSet<T>(comparator);
 }
 public void push(T o){
   treeSet.add(o);
 }
 public TreeSet<T> getTreeSet(){
   return this.treeSet;
 }
}

問題は、bigHeap が 3 回 (異なるオブジェクト) プッシュするのに、結局 1 つのオブジェクトしか保持しない理由です。

4

1 に答える 1

0

Setこれは、要素の重複を許可しない理由に起因する可能性があるものです。

タイプのオブジェクトをbigHeap という名前ItemCacheNodeのADT にプッシュしています。ここで、 docssetに従って、新しいオブジェクトがセットに追加されると、

要素は、使用されるコンストラクターに応じて、自然順序付けを使用するか、セットの作成時に提供される Comparator によって順序付けられます。

TreeSet Treesetがインターフェイスを使用して正しく実装されていない場合、誤ったコンパレータがネイティブの equals メソッドをオーバーライドしSetます。前述のドキュメントに従って、

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

あなたの定義、

private TreeSet<T> treeSet = new TreeSet<T>(comparator);

はインターフェイスの使用を無視し、その結果、 の非重複機能の一般的な考え方に準拠していないため、この誤った機能を示しましたSet

于 2016-03-22T03:05:32.103 に答える