Reputation: 53
I'm a Java newbie attempting to build a program that counts the unique words given a text file using a data structure. For practice sake, I implemented the data structure and abstract class myself. However, when I run the program, I get stuck in an infinite loop when it comes to the add method is MyArrayList.
The objects in this case is a SingleWord object consisting of a string word and integer count to keep track of the frequency. I haven't included the class to create the object here.
public class MyArrayList<E> extends MyAbstractList<E> {
public static final int INITIAL_CAPACITY = 16;
private E[] data = (E[])new Object[INITIAL_CAPACITY];
/** Create a default list */
public MyArrayList() {
}
/** Create a list from an array of objects */
public MyArrayList(E[] objects) {
for (int i = 0; i < objects.length; i++)
add(objects[i]); // Warning: don’t use super(objects)!
}
@Override /** Add a new element at the specified index */
public void add(int index, E e) {
ensureCapacity();
// Move the elements to the right after the specified index
for (int i = size - 1; i >= index; i--)
data[i + 1] = data[i];
// Insert new element to data[index]
data[index] = e;
// Increase size by 1
size++;
}
/** Create a new larger array, double the current size + 1 */
private void ensureCapacity() {
if (size >= data.length) {
E[] newData = (E[])(new Object[size * 2 + 1]);
System.arraycopy(data, 0, newData, 0, size);
data = newData;
}
}
@Override /** Clear the list */
public void clear() {
data = (E[])new Object[INITIAL_CAPACITY];
size = 0;
}
@Override /** Return true if this list contains the element */
public boolean contains(E e) {
for (int i = 0; i < size; i++)
if (e.equals(data[i])) return true;
return false;
}
@Override /** Return the element at the specified index */
public E get(int index) {
checkIndex(index);
return data[index];
}
private void checkIndex(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException
("index " + index + " out of bounds");
}
@Override /** Return the index of the first matching element
* in this list. Return -1 if no match. */
public int indexOf(E e) {
for (int i = 0; i < size; i++)
if (e.equals(data[i])) return i;
return -1;
}
@Override /** Return the index of the last matching element
* in this list. Return -1 if no match. */
public int lastIndexOf(E e) {
for (int i = size - 1; i >= 0; i--)
if (e.equals(data[i])) return i;
return -1;
}
@Override /** Remove the element at the specified position
* in this list. Shift any subsequent elements to the left.
* Return the element that was removed from the list. */
public E remove(int index) {
checkIndex(index);
E e = data[index];
// Shift data to the left
for (int j = index; j < size - 1; j++)
data[j] = data[j + 1];
data[size - 1] = null; // This element is now null
// Decrement size
size--;
return e;
}
@Override /** Replace the element at the specified position
* in this list with the specified element. */
public E set(int index, E e) {
checkIndex(index);
E old = data[index];
data[index] = e;
return old;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder("[");
for (int i = 0; i < size; i++) {
result.append(data[i]);
if (i < size - 1) result.append(", ");
}
return result.toString() + "]";
}
/** Trims the capacity to current size */
public void trimToSize() {
if (size != data.length) {
E[] newData = (E[])(new Object[size]);
System.arraycopy(data, 0, newData, 0, size);
data = newData;
} // If size == capacity, no need to trim
}
@Override /** Override iterator() defined in Iterable */
public java.util.Iterator<E> iterator() {
return new ArrayListIterator();
}
private class ArrayListIterator
implements java.util.Iterator<E> {
private int current = 0; // Current index
@Override
public boolean hasNext() {
return (current < size);
}
@Override
public E next() {
return data[current++];
}
@Override
public void remove() {
MyArrayList.this.remove(current);
}
}
public static StringWord compare(StringWord w1, StringWord w2, Comparator<StringWord> c) {
if(c.compare(w1.word,w2.word) > 0)
return w1;
else
return w2;
}
}
and this is my abstract class
public abstract class MyAbstractList<E> implements MyList<E> {
protected int size = 0; // The size of the list
/** Create a default list */
protected MyAbstractList() {
}
/** Create a list from an array of objects */
protected MyAbstractList(E[] objects) {
for (int i = 0; i < objects.length; i++)
add(objects[i]);
}
/** Add a new element at the end of this list */
@Override
public void add(E e) {
add(size, e);
}
@Override /** Return true if this list contains no elements */
public boolean isEmpty() {
return size == 0;
}
@Override /** Return the number of elements in this list */
public int size() {
return size;
}
@Override /** Remove the first occurrence of the element e
* from this list. Shift any subsequent elements to the left.
* Return true if the element is removed. */
public boolean remove(E e) {
if (indexOf(e) >= 0) {
remove(indexOf(e));
return true;
}
else
return false;
}
}
and this is my interface MyList
public interface MyList<E> extends java.lang.Iterable<E> {
/** Add a new element at the end of this list */
public void add(E e);
/** Add a new element at the specified index in this list */
public void add(int index, E e);
/** Clear the list */
public void clear();
/** Return true if this list contains the element */
public boolean contains(E e);
/** Return the element from this list at the specified index */
public E get(int index);
/** Return the index of the first matching element in this list.
* Return -1 if no match. */
public int indexOf(E e);
/** Return true if this list contains no elements */
public boolean isEmpty();
/** Return the index of the last matching element in this list
* Return -1 if no match. */
public int lastIndexOf(E e);
/** Remove the first occurrence of the element o from this list.
* Shift any subsequent elements to the left.
* Return true if the element is removed. */
public boolean remove(E e);
/** Remove the element at the specified position in this list
* Shift any subsequent elements to the left.
* Return the element that was removed from the list. */
public E remove(int index);
/** Replace the element at the specified position in this list
* with the specified element and returns the new set. */
public Object set(int index, E e);
/** Return the number of elements in this list */
public int size();
/** Return an iterator for the list */
public java.util.Iterator<E> iterator();
}
Main method etc
import java.io.*;
import java.util.*;
import javax.swing.JOptionPane;
public class DataStruc{
public static void main(String[] args) throws Exception{
boolean continueProcess = false;
Scanner input;
MyList<SingleWord> list = new MyArrayList<SingleWord>();
//prompt user for input
do {
input = readFile(continueProcess).useDelimiter("[^A-Za-z]+");
//process input(file)
while (input.hasNext()) {
list.add(new SingleWord(input.next()));
}
System.out.println(list);
//prompt user to continue input
int option = JOptionPane.showConfirmDialog(
null,
"Continue opening file?",
"Select an Option",
JOptionPane.YES_NO_OPTION );
continueProcess = (option == 0)? true : false;
} while(continueProcess);
}
public static Scanner readFile(boolean continueProcess) throws Exception{
String filename;
File file;
do {
filename = JOptionPane.showInputDialog("Enter file name:");
file = new File(filename);
if (file.exists()) { //if file exist, process the file
System.out.println("\"" + filename + "\"" + " is found.");
continueProcess = false;
} else if (filename == null) { //if user click cancel
System.exit(0);
} else if(filename.length() == 0) { //if user click yes without entering any value
System.out.println("No file name has been entered.");
System.out.println("Please try again.");
continueProcess = true;
}
else{ //if the file does not exist
System.out.println("File " +
"\"" + filename + "\"" +
" does not exist");
continueProcess = true;
}
} while(continueProcess);
return new Scanner(file);
}
}
Class to create SingleWord object
public class SingleWord{
private int count = 1;
private String word;
public SingleWord(String word){
this.word = word;
}
public String getWord() {
return word;
}
public int getCount() {
return count;
}
@Override
public String toString() {
return word;
}
}
Sorry and thank you :'(
Text file is here:
An article (abbreviated art) is a word (or prefix or suffix) that is used with a noun to indicate the type of reference being made by the noun. Articles specify grammatical definiteness of the noun, in some languages extending to volume or numerical scope. The articles in the English language are the and a/an, and (in some contexts) some. 'An' and 'a' are modern forms of the Old English 'an', which in Anglian dialects was the number 'one' (compare 'on', in Saxon dialects) and survived into Modern Scots as the number 'ane'. Both 'on' (respelled 'one' by the Normans) and 'an' survived into Modern English, with 'one' used as the number and 'an' ('a', before nouns that begin with a consonant sound) as an indefinite article. they're "a"
Upvotes: 0
Views: 1421
Reputation: 1138
Offcourse it's infinite loop, you're calling same method recursively. You have to change compare method code block like this:
public static SingleWord compare(SingleWord w1, SingleWord w2, Comparator<String> c) {
if (c.compare(w1.getWord(), w2.getWord()) > 0) {
return w1;
} else {
return w2;
}
}
Upvotes: 0
Reputation: 3599
It's because the add method of your abstract class is calling itself.
@Override
public void add(E e) {
add(e);
}
I suppose you wanted something more like:
@Override
public void add(E e) {
add(size, e);
}
Upvotes: 5