我有以下代码:
public class EnglishWord implements Comparable<EnglishWord> {
private String word;// unique
private int occurenceNumber; //not unique
public EnglishWord(String word, int occurenceNumber) {
this.word = word;
this.occurenceNumber= occurenceNumber;
}
public boolean equals(EnglishWord anotherWord) {
return word.equals(anotherWord.getWord());
}
public int compareTo(EnglishWord anotherWord) {
return occurenceNumber - anotherWord.getOccurenceNumber;
}
我想将所有EnglishWord
添加到Set
,其中每个唯一EnglishWord
只有一个word
对象。我希望Set
按occurrenceNumber
排序。我已经按occurrenceNumber
对单词进行了排序,但没有将EnglishWord
添加到occurrenceNumber
的唯一Set
。作为代码,这就是我的意思:
Set<EnglishWord> mySet= new TreeSet<EnglishWord>();
mySet.add(new EnglishWord("hello",8));
mySet.add(new EnglishWord("hi",8));
在此之后,mySet
的大小为1。
答案 0 :(得分:4)
您可能希望按occurenceNumber进行比较,如果是0
,则按字词进行比较
public int compareTo(EnglishWord anotherWord) {
int val = occurenceNumber.compareTo(anotherWord.occurenceNumber);
if (val == 0){ //ok, these have the same occurence, but are they the same word?
val = word.compareTo(other.word);
}
return val;
}
答案 1 :(得分:4)
您应该定义equals和hashCode,或者不定义它们。在您的代码中,对于EnglishWord的两个x和y实例,x.equals(y) == true
同时x.hashCode() != y.hashCode()
会发生。如果您希望您的类使用java.util中的集合类,那么这是不合法的。见the Object JavaDoc。要解决此问题,请添加以下内容:
@Override
public int hashCode() {
return this.word.hashCode();
}
equals方法必须具有签名“public boolean equals(Object other)” - 您的equals采用EnglishWord参数,这会导致您的方法被忽略。修正:
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (other.getClass() != this.getClass()) return false;
final EnglishWord ow = (EnglishWord) other;
return ow.word.equals(this.word);
}
通常,使用@Override
注释可以帮助您更好地对抗这种错误,因为运行时错误会以这种方式转换为编译时错误。
此外,您对Comparable
接口的实现应该可以使用泛型。
答案 2 :(得分:1)
TreeSet
由TreeMap
内部支持。 TreeMap.put(Object, Ojbect)
将使用compareTo
上的EnglishWord
方法来确定新元素在树中的位置。如果compareTo
的结果为0,则该方法假设元素相等。
这与TreeSet.add
将指定的元素添加到此集合中 如果它还没有出现。更多 正式地,添加指定的元素e 如果集合包含否,则为此集合 元素e2这样(e == null? e2 == null:e.equals(e2))。如果这个设定 已包含元素,调用 保持设置不变并返回 假的。
Comparable
的JavaDoc说
强烈建议,但并非严格要求(x.compareTo(y)== 0)==(x.equals(y))。一般来说,任何实现Comparable接口并且违反此条件的类都应该清楚地表明这一事实。推荐的语言是“注意:此类具有与equals不一致的自然顺序。”
您需要接受此建议,并在事件发生时进行比较。
答案 3 :(得分:0)
一个集合只能有一个索引和一个排序。你想要的是两个凹凸,一个确保单词是唯一的,另一个是按出现次数排序。
要做到这一点,你需要维护两个集合,一个集合,一个单词用单词键入唯一性,第二个集合按出现和单词排序。
注意:以这种方式在集合中使用的字段无法更改,否则您将获得不正确的行为。我建议你让场地最后。