Tristan Madden
Tristan Madden

Reputation: 19

Preventing duplicate objects from being added to an ArrayList or HashSet

So my goal is to take a String and split it into an array of Word objects. I only want one object to represent one English word, meaning that duplicate words should be filtered out before being added to the array. I can't for the life of me figure out why my criteria for filtering out duplicate words are failing. I've tried both the ArrayList and HashSet. My goal is to also count the instances of that word in the String but I haven't implemented that yet.

package sandbox;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class Sandbox {

public static void main(String[] args) {

    String original = "the quick brown fox jumps over the lazy dog the quick brown fox jumps over the lazy dog";
    int wordCount = counter(original);//Count the words using a method
    Word[] word = new Word[wordCount];
    List<Word> wordList = new ArrayList<>();
    HashSet wordSet = new HashSet();

    for (int i = 0; i < wordCount; i++) {
        String[] parts = original.split(" ");//Splits the String.
        word[i] = new Word();//Instantiates a Word object.
        word[i].setWord(parts[i], 1);//Sets Word object values.

        if (wordSet.contains(word[i])) {//Criteria for adding the Word object to the HashSet.
            System.out.println("Duplicate detected.");
        } else {
            wordSet.add(word[i]);//Adds the Word object to a HashSet.
        }

        if (wordList.contains(word[i])) {//Criteria for adding the Word object to the ArrayList.
            System.out.println("Duplicate detected.");
        } else {
            wordList.add(word[i]);//Adds the Word object to the ArrayList.
        }

    }

    System.out.println("wordSet size: " + wordSet.size() + " | wordList size: " + wordList.size());
    for (int i = 0; i < wordCount; i++) {

        System.out.println(wordList.get(i));

    }
    System.out.println(wordSet.toString());
}

public static int counter(String s) {

    int wordCount = 0;

    boolean word = false;
    int endOfLine = s.length() - 1;

    for (int i = 0; i < s.length(); i++) {
        // if the char is a letter, word = true.
        if (Character.isLetter(s.charAt(i)) && i != endOfLine) {
            word = true;
            // if char isn't a letter and there have been letters before,
            // counter goes up.
        } else if (!Character.isLetter(s.charAt(i)) && word) {
            wordCount++;
            word = false;
            // last word of String; if it doesn't end with a non letter, it
            // wouldn't count without this.
        } else if (Character.isLetter(s.charAt(i)) && i == endOfLine) {
            wordCount++;
        }
    }
    return wordCount;
}

}

and my Word class:

package sandbox;

public class Word {

private String word = "";
private int count;

public Word() {

    word = "";
    count = 0;

}

public void setWord(String w, int c) {
    word = w;
    count = c;

}

public void getWord() {
    System.out.println(word + ", " + count);
}

public boolean duplicate(Word word2) {

    return this.word.equals(word2.word);

}

@Override
public String toString() {
    return ("word: " + this.word + " | count: " + count);
}

public boolean equals(Word word2) {
    return this.word.equals(word2.word);
}
}

this is my current output:

wordSet size: 18 | wordList size: 18

word: the | count: 1

word: quick | count: 1

word: brown | count: 1

word: fox | count: 1

word: jumps | count: 1

word: over | count: 1

word: the | count: 1

word: lazy | count: 1

word: dog | count: 1

word: the | count: 1

word: quick | count: 1

word: brown | count: 1

word: fox | count: 1

word: jumps | count: 1

word: over | count: 1

word: the | count: 1

word: lazy | count: 1

word: dog | count: 1

Upvotes: 1

Views: 555

Answers (1)

Eran
Eran

Reputation: 393771

You are not overriding Object's equals. You are overloading it. To override it, the argument type should be an Object :

It should be :

@Override
public boolean equals(Object other) {
    if (!(other instanceof Word)) return false;
    Word word2 = (Word) other;
    return this.word.equals(word2.word);
}

For HashSet to behave properly, you must also override hashCode.

Upvotes: 2

Related Questions