Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort Set by not unique data?

Tags:

java

I have the following code:

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;
    }

I want to add all EnglishWords in to a Set where there's exactly one EnglishWord object for each unique word. I want the Set to be sorted by occurrenceNumber. The code I have already sorts the words by occurrenceNumber, but doesn't add EnglishWord with unique occurrenceNumber to the Set. As code, here is what I mean:

Set<EnglishWord> mySet= new TreeSet<EnglishWord>();
mySet.add(new EnglishWord("hello",8));
mySet.add(new EnglishWord("hi",8));

After this, mySet's size is 1.

like image 755
Victoria Seniuk Avatar asked Jan 21 '23 10:01

Victoria Seniuk


1 Answers

You should either define both equals and hashCode or none of them. In your code, for two instances x and y of EnglishWord, it will happen that x.equals(y) == true while x.hashCode() != y.hashCode(). This is not legal if you expect your class to work with the collection classes from java.util. See the Object JavaDoc. To fix this, add something like this:

@Override
public int hashCode() {
    return this.word.hashCode();
}

The equals method must have the signature "public boolean equals(Object other)" -- your equals takes an EnglishWord parameter which results in your method being essentially ignored. Fix:

@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);
}

Generally, using the @Override annotation can help a lot to make your coding more robust against this kind of mistake as the runtime error is turned into a compile time error this way.

Additionally, your implementation of the Comparable interface should probably make use of generics.

like image 166
Waldheinz Avatar answered Feb 01 '23 19:02

Waldheinz