按一个值对java对象集合进行排序,并按另一个值保持唯一
我需要按整数值“level”对java对象集合进行排序。我还需要确定此集合是否已包含按“title”排序的对象 我相信一个集合的最佳选择是一个树集,它拥有一组有序的唯一值 我有一个具有“level”和“title”属性的对象。它实现了如下类似的功能: 它覆盖Equals方法(用于检查对象是否已包含在树集中的“title”中) 代码如下所示:按一个值对java对象集合进行排序,并按另一个值保持唯一,java,collections,arraylist,comparator,treeset,Java,Collections,Arraylist,Comparator,Treeset,我需要按整数值“level”对java对象集合进行排序。我还需要确定此集合是否已包含按“title”排序的对象 我相信一个集合的最佳选择是一个树集,它拥有一组有序的唯一值 我有一个具有“level”和“title”属性的对象。它实现了如下类似的功能: 它覆盖Equals方法(用于检查对象是否已包含在树集中的“title”中) 代码如下所示: @Override public boolean equals(Object arg0) { Artifact obj = (Artifact)
@Override
public boolean equals(Object arg0) {
Artifact obj = (Artifact) arg0;
if (this.getTitle().equals(obj.getTitle())) {
return true;
}
return false;
}
@Override
public int compareTo(Artifact aThat) {
final int BEFORE = -1;
final int EQUAL = 0;
final int AFTER = 1;
if (this == aThat) return EQUAL;
if (this.level < aThat.level) return BEFORE;
if (this.level > aThat.level) return AFTER;
assert this.equals(aThat) : "compareTo inconsistent with equals.";
return EQUAL;
}
@覆盖
公共布尔等于(对象arg0){
工件obj=(工件)arg0;
如果(this.getTitle().equals(obj.getTitle()){
返回true;
}
返回false;
}
@凌驾
公共int比较(工件aThat){
之前的最终整数=-1;
最终整数等于0;
之后的最终整数=1;
如果(this==aThat)返回相等值;
如果(本级<本级)在之前返回;
如果(this.level>aThat.level)在之后返回;
断言此。等于(aThat):“与等于不一致。”;
回报相等;
}
当我尝试从可能具有重复值的arraylist向列表中添加值时。contains似乎不起作用,不管怎样,对象都会添加到TreeSet。以下是代码:
TreeSet<Artifact> subsetOfArtifacts = new TreeSet<Artifact>();
ArrayList<Artifact> allArtifacts = getArtifacts();
Iterator<Artifact> allArtifactsIter = allArtifacts.iterator();
while (allArtifactsIter.hasNext()) {
Artifact artifact = (Artifact) allArtifactsIter.next();
if (!subsetOfArtifacts.contains(artifact)) {
subsetOfArtifacts.add(artifact);
}
}
TreeSet subsetOfArtifacts=newtreeset();
ArrayList allArtifacts=getArtifacts();
迭代器allArtifactsIter=allArtifacts.Iterator();
while(allArtifactsIter.hasNext()){
工件工件=(工件)allArtifactsIter.next();
如果(!subsetOfArtifacts.contains(artifact)){
添加(工件);
}
}
理想情况下,我希望有一个按级别排序的所有唯一工件的列表。我如何做到这一点?不仅需要compare来比较级别,还需要它来比较标题,因为equals比较标题
public int compareTo(Artifact aThat) {
final int BEFORE = -1;
final int EQUAL = 0;
final int AFTER = 1;
if ( this == aThat ) return EQUAL;
if (this.level < aThat.level) return BEFORE;
if (this.level > aThat.level) return AFTER;
return this.getTitle().compareTo(aThat.getTitle());
// assert this.equals(aThat) : "compareTo inconsistent with equals.";
// return EQUAL;
}
public int compareTo(工件aThat){
之前的最终整数=-1;
最终整数等于0;
之后的最终整数=1;
如果(this==aThat)返回相等值;
如果(本级<本级)在之前返回;
如果(this.level>aThat.level)在之后返回;
返回这个.getTitle().compareTo(aThat.getTitle());
//断言此。等于(aThat):“与等于不一致。”;
//回报相等;
}
此外,正如Bohemian提到的,如果覆盖equals(),则应覆盖hashCode(),但这不是树集允许添加重复项的原因。如果覆盖,则也应覆盖!否则,集合(尤其是集合)的行为未定义。应将此方法添加到类中:
@Override
public int hashCode() {
return title.hashCode();
}
接下来,您应该使用HashSet,并使用Set-sortedSet=new-TreeSet(Set);
进行排序。一旦您这样做,它应该可以正常工作
原因是哈希表依赖于这样一个事实:如果两个对象是equal()
,那么它们的hashCode()
也是相等的
hashCode的总合同为:
- 每当在Java应用程序的执行过程中对同一对象多次调用hashCode时,hashCode方法必须一致 如果在equals中未使用任何信息,则返回相同的整数 已修改对象上的比较。不需要保留此整数 从应用程序的一次执行到另一次执行的一致性 同样的应用
- 如果根据equals(Object)方法,两个对象相等,则必须对这两个对象中的每一个调用hashCode方法 生成相同的整数结果
- 根据equals(java.lang.Object)方法,如果两个对象不相等,则不需要调用 这两个对象中的每一个都必须产生不同的整数结果。 但是,程序员应该知道,生成不同的 不相等对象的整数结果可能会提高 哈希表
2个相等的对象必须生成相等的哈希代码。比较器应首先检查级别,然后检查标题,如果您希望它先按级别再按标题排序,并且仅当级别和标题都相等时才返回相等。类似于以下内容:
@Override
public int compareTo(Artifact aThat)
{
final int BEFORE = -1;
final int EQUAL = 0;
final int AFTER = 1;
if ( this == aThat ) return EQUAL;
if( this.level < aThat.level ) return BEFORE;
if( this.level > aThat.level ) return AFTER;
int compare = this.getTitle().compareTo(aThat.getTitle());
if( compare != EQUAL ) return compare;
assert this.equals(aThat) : "compareTo inconsistent with equals.";
return EQUAL;
}
@覆盖
公共int比较(工件aThat)
{
之前的最终整数=-1;
最终整数等于0;
之后的最终整数=1;
如果(this==aThat)返回相等值;
如果(this.levelaThat.level)在之后返回;
int compare=this.getTitle().compareTo(aThat.getTitle());
如果(比较!=相等)返回比较;
断言此。等于(aThat):“与等于不一致。”;
回报相等;
}
在发布之前,我没有看到rob的答案。这也将迫使您拥有唯一的级别。最好的解决方案可能是一种显而易见的、简单的、多步骤的方法,而不是试图将所有这些都放在一个数据结构中。您在运行
-ea
switchwhat hashset时启用了断言吗?他只谈到treesetsIt i如果他想要树集,就不必使用哈希集。