Reputation: 111
The project I am working on right now involves me reading words from a text file and loading them into an array (and eventually a binary tree, but that will be finished later). I must load both the word and the word's frequency (initially 1) into the array, so I have packed both variables into an object WordNode
. I am able to load the words into the array, but things fall apart when I try to check if a word is already in the array. If it is, I must increase the frequency by 1. However, my code does not even check the word and simply adds it anyway (I presume it's checking the reference to the variable and not the word itself). Below is my main
method and the WordNode
class.
Main method:
public class Driver {
/////////////// fields ///////////////
public static ArrayUnorderedList<WordNode> wordArray = new ArrayUnorderedList<WordNode>();
public static LinkedBinarySearchTree<WordNode> wordTree = new LinkedBinarySearchTree<WordNode>(); //tree to hold words
/////////////// methods ///////////////
public static void main(String[] args) throws Exception {
//ask for filename
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the name of the file to read from: ");
Reader file = new FileReader(reader.readLine());
//read file
Scanner input = new Scanner(file);
while(input.hasNext()) {
//get words from file
String word = input.next();
//remove non-word characters and convert to lowercase
word = word.replaceAll("\\W", "");
word = word.toLowerCase();
//create node
WordNode newWord = new WordNode(word);
//if word is already in array
if(wordArray.contains(newWord)) {
System.out.println("Word is already in array");
//increment frequency by 1
int index = wordArray.find(newWord);
wordArray.list[index].setFrequency(wordArray.list[index].getFrequency() + 1);
System.out.println(newWord.getWord() + newWord.getFrequency());
} else {
System.out.println("Word is not yet in array");
//add word to tree
System.out.println(newWord.getWord());
wordArray.addToRear(newWord);
}
}
//insert into tree
//perform traversals on tree
}
WordNode class:
public class WordNode {
protected String word;
protected WordNode left, right;
protected int frequency;
/**
* Creates a new node with the specified data.
* @param obj the element that will become a part of the new node
*/
WordNode(String obj) {
word = obj;
left = null;
right = null;
frequency = 1;
}
/**
* Gets the word.
* @return the word
*/
public String getWord() {
return word;
}
/**
* Sets the word.
* @param word the word to set
*/
public void setWord(String word) {
this.word = word;
}
/**
* Gets the left.
* @return the left
*/
public WordNode getLeft() {
return left;
}
/**
* Sets the left.
* @param left the left to set
*/
public void setLeft(WordNode left) {
this.left = left;
}
/**
* Gets the right.
* @return the right
*/
public WordNode getRight() {
return right;
}
/**
* Sets the right.
* @param right the right to set
*/
public void setRight(WordNode right) {
this.right = right;
}
/**
* Gets the frequency.
* @return the frequency
*/
public int getFrequency() {
return frequency;
}
/**
* Sets the frequency.
* @param frequency the frequency to set
*/
public void setFrequency(int frequency) {
this.frequency = frequency;
}
}
Some methods from the ArrayList class:
/**
* Returns true if this list contains the specified element.
* @param target the element that the list is searched for
* @return true if the target is in the list, false if otherwise
*/
public boolean contains(T target) {
return (find(target) != NOT_FOUND);
}
/**
* Returns the array index of the specified element, or the
* constant NOT_FOUND if it is not found.
* @param target the element that the list will be searched for
* @return the integer index into the array containing the target element, or the NOT_FOUND constant
*/
public int find(T target) {
int scan = 0, result = NOT_FOUND;
boolean found = false;
if (!isEmpty()) {
while (!found && scan < rear) {
if (target.equals(list[scan])) {
found = true;
} else {
scan++;
}
}
}
if (found) {
result = scan;
}
return result;
}
Upvotes: 2
Views: 1412
Reputation: 1982
You need to override eqauls in your WordNode:
public boolean equals(Object o) {
if(o instanceof WordNode) {
WordNode temp = (WordNode) o;
return(temp.getWord().equals(this.word));
}
else
System.out.println("Object o you passed is not a WordNode");
}
This way if two different WordNode object has the same String as word field they are considered equals
how to call the equals:
WordNode n1 = new WordNode();
n1.setWord("test");
WordNode n2 = new WordNode();
n2.setWord("test");
System.out.println(n1.equals(n2));
So the equals receives an object of type Object but when you call the equals on a WordNode you havo to provide an object which is instance of WordNode too otherwise the cast i made fails (your exception) and of course it makes no sense to verify if an Object is equal to a WordNode
Upvotes: 0
Reputation: 86754
The immediate reason your code doesn't work is that ArrayUnorderedList#contains()
probably relies on the equals()
method to determine if the entry is in the list. Without seeing the definition of the class it's impossible to know.
Since you haven't provided an override of equals()
, it's using object identity (the default from Object
) so every WordNode
is distinct from every other WordNode
.
If you want to use ArrayUnorderedList
then you must implement WordNode#equals()
with the correct behavior.
However, you should consider using a Map<String,Integer>
(or Map<String,WordNode>
) instead to store the frequencies. This will be much faster.
Upvotes: 4