2014-10-20 53 views
0

执行比较我有这样的和平代码:元素后取出在TreeSet中

final SortedSet<NisType> lAllNNisType = new TreeSet<NisType>(new NisTypeComparator()); 
lAllNisType.addAll(pAllNisType); // where pAllNisType is of type ArrayList<NisType> 

这就是我比较类:

private class NisTypeComparator implements Comparator<NisType> { 

    @Override 
    public int compare(NisType pNisType, NisType pNisType2) { 
     if (pNisType.getPrio()>pNisType2.getPrio()) 
     return 1; 
     else if (pNisType.getPrio()<pNisType2.getPrio()) 
     return -1; 
     else 
     return 0; 
    } 
    } 

我的ArrayList pAllNisType充满了6个不同的对象(基于平等和hashCode方法)。 后然而这一行被执行:

lAllNisType.addAll(pAllNisType); 

lAllNisType只包含5个对象。 有一个比较返回0.并且由于这一个对象已从lAllNisType中删除。

我不知道这里发生了什么。 对象不同。如果我做这样的事情:

final Set<NisType> lAllNisType = new HashSet<NisType>(pAllNisType); 

lAllNisType有6个元素。

感谢您的帮助

斯特凡

+1

然后你的'比较器'比较不同于'equals'和'hashCode'。当然是 – 2014-10-20 15:18:51

+0

。为什么这很重要? – 2014-10-20 15:20:22

+0

这就解释了为什么你在'TreeSet'中有5个元素,而在'HashSet'中有6个元素。 – 2014-10-20 15:20:56

回答

1

是的,这恰恰表现为documented.

注意,排序由有序集合维护(无论是否提供了明确的比较器)如果有序集合要正确实现Set接口,则必须与equals保持一致。 (请参见Comparable接口或Comparator接口以获得与equals一致的精确定义。)这是因为Set接口是根据equals操作定义的,但排序集使用它的compareTo(或compare)方法执行所有元素比较,,所以从排序集的角度来看,通过这种方法被认为相等的两个元素等于。即使排序与等号不一致,排序集的行为也是很好定义的;它只是不服从Set接口的总体合同。

如果compare返回0,那么就集合而言,两个元素被认为是相等的,并且只有其中一个元素可以出现在集合中。如果你想保留这两个对象,你需要让你的比较器区分它们,例如通过二次订购。