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 次(不同的对象)但毕竟只持有一个对象。

4

1 回答 1

0

这可以归因于Set不允许重复元素的原因。

您将类型的对象推ItemCacheNodeset名为 bigHeap 的 ADT。现在,当一个新对象被添加到集合中时,根据文档

元素使用它们的自然顺序或在集合创建时提供的 Comparator 进行排序,具体取决于使用的构造函数。

如果未使用接口正确实现 Treeset,则TreeSet 错误的比较器将覆盖原本的声音 equals 方法。Set根据上述文档,

请注意,如果要正确实现 Set 接口,集合维护的顺序(无论是否提供显式比较器)必须与 equals 一致。(参见 Comparable 或 Comparator 以获得与 equals 一致的精确定义。)这是因为 Set 接口是根据 equals 操作定义的,但是 TreeSet 实例使用其 compareTo(或 compare)方法执行所有元素比较,所以两个从集合的角度来看,这种方法认为相等的元素是相等的。一个集合的行为是明确定义的,即使它的顺序与equals不一致;它只是不遵守 Set 接口的一般约定。

你的定义,

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

忽略了接口的使用,结果显示了这个错误的功能,不符合 a 的非重复功能的一般概念Set

于 2016-03-22T03:05:32.103 回答