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;
}
The immediate reason your code doesn’t work is that
ArrayUnorderedList#contains()probably relies on theequals()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 fromObject) so everyWordNodeis distinct from every otherWordNode.If you want to use
ArrayUnorderedListthen you must implementWordNode#equals()with the correct behavior.However, you should consider using a
Map<String,Integer>(orMap<String,WordNode>) instead to store the frequencies. This will be much faster.