【问题标题】:Why the TreeSet can only hold one object when i push three in it?为什么当我推入三个对象时,TreeSet 只能容纳一个对象?
【发布时间】:2012-02-20 15:03:10
【问题描述】:

我想将一些对象推入 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 次(不同的对象),但毕竟只持有一个对象。

【问题讨论】:

  • 听起来您的所有三个ItemCacheNode 对象比较相等,因此每个对象都“淘汰”其前身。您可以发布您的Comparator&lt;ItemCacheNode&gt; 实现的compare 方法的内容吗?
  • 问题可能出在比较器上。看起来 Set 认为所有 3 个节点都是平等的。
  • 谢谢大家...这是我的 Comparator 造成的问题,它们是相等的对象。

标签: jakarta-ee treeset java


【解决方案1】:

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

您正在将 ItemCacheNode 类型的对象推入名为 bigHeap 的 set ADT。现在,当一个新对象被添加到集合中时,根据docs

元素使用它们的自然顺序进行排序,或者通过 在设置创建时间提供比较器,具体取决于哪个 使用了构造函数。

错误的比较器会覆盖 TreeSet 原生的其他声音等于方法 iff 使用 Set 接口未正确实现 Treeset。根据上述文档,

请注意,由集合维护的顺序(无论是否显式 提供了比较器)必须与equals一致,如果它是 正确实现 Set 接口。 (见可比较或比较 用于与等于一致的精确定义。)就是这样 因为 Set 接口是根据 equals 操作定义的, 但是 TreeSet 实例使用它的执行所有元素比较 compareTo(或比较)方法,因此两个元素被视为相等 通过这种方法,从集合的角度来看,它们是相等的。这 一个集合的行为是明确定义的,即使它的顺序是不一致的 等于;它只是不遵守集合的一般合同 界面。

你的定义,

private TreeSet&lt;T&gt; treeSet = new TreeSet&lt;T&gt;(comparator);

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 2021-06-04
    • 1970-01-01
    相关资源
    最近更新 更多