为什么当我推入三个对象时,TreeSet只能容纳一个对象?

为什么当我推入三个对象时,TreeSet只能容纳一个对象?

问题描述:

我想某些对象推到一个TreeSet(里面BigHeap类),但我有问题:为什么当我推入三个对象时,TreeSet只能容纳一个对象?

这里是我的主类:

# --------- 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推三次(不同的对象),但只持有一个对象。

+6

听起来好像所有的三个'ItemCacheNode'对象都是相等的,所以每个对象都会“淘汰”它的前任。你可以发布你的'Comparator '实现的'compare'方法的内容吗? – ruakh 2012-02-20 15:06:33

+2

问题可能出在比较器上。它看起来像集合认为所有3个节点相等。 – Ingo 2012-02-20 15:06:39

+0

感谢球员......这是我的比较器导致的问题,他们是等于对象。 – MrROY 2012-02-20 15:19:33

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

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

的元件使用他们的自然顺序进行排序,或者由一 比较集合创建时提供,这取决于所使用 构造。

错误比较器会覆盖否则声音equals方法原产于一个TreeSetIFF的TreeSet中未使用Set接口正确实现。按照上述文档,

注意,由一组(无论是否提供了明确的 比较器)保持的顺序必须与equals一致,如果它是 正确实现Set接口。 (参见可比或比较 为一致的精确定义与equals)。这是这样 因为Set接口是按照equals操作, 但TreeSet实例来定义使用其 的compareTo执行所有元件比较(或比较)方法,所以从这个方法看,被这个方法认定为相等的两个元素是相等的。即使其排序不一致, 的行为也是明确定义的,即等于 ;它只是不服从集合 接口的总体合同。

你的定义,

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

忽略接口的利用率,因此,表现出这种错误的功能,由不的Set的非复制功能的总体思路行事。