This question is a follow-up question of this question. These features are added to the new class -
Generic
class- User is capable of setting the size
List interface
has been addedIterator
class has been added
As of now I still have some questions after developing this class.
- Does this
list interface
have enough methods/behavior? - Why do I have to type cast from
next()
while returning data? - When I am testing this class I have to do this
Iterator<Integer> itr = ((UnorderedList) ul).iterator();
why?
Thanks to him to open my eyes to design a class to iterate over a structure. My prof of Data Structure even did not specify or taught students important things like this.
If this class is still lacking anything then as always suggestions and advice are appreciated.
//List interface
package lists.arrayLists;
public interface List<T>
{
boolean isFull();
boolean isEmpty();
boolean add(T data);
void remove(T data);
boolean find(T data);
int size();
}
// Unordered List class
package lists.arrayLists.unorderedList;
import lists.arrayLists.List;
import java.lang.IndexOutOfBoundsException;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class UnorderedList<T> implements List<T>, Iterable<T>
{
private static int MAX_SIZE = 100;
private int size;
private Node<T>[] nodeElements;
public UnorderedList()
{
nodeElements = new Node[MAX_SIZE];
}
public UnorderedList(int capacity)
{
MAX_SIZE = capacity;
nodeElements = new Node[MAX_SIZE];
}
@Override
public boolean isFull()
{
return (size() == MAX_SIZE);
}
@Override
public boolean isEmpty()
{
return (size() == 0);
}
@Override
public int size()
{
return size;
}
@Override
public boolean add(T data)
{
try
{
Node<T> node = new Node<>(data);
nodeElements[size++] = node;
return true;
}
catch (IndexOutOfBoundsException ex)
{
System.out.println(ex.getMessage());
throw new IndexOutOfBoundsException();
}
}
@Override
public void remove(T data)
{
int index = locate(data);
try
{
nodeElements[index] = nodeElements[size() - 1];
size--;
}
catch (IndexOutOfBoundsException ex)
{
throw new NoSuchElementException();
}
}
@Override
public boolean find(T data)
{
return (locate(data) >= 0);
}
private int locate(T data)
{
for (int index = 0; index < size(); index++)
{
if (data == nodeElements[index].getData())
{
return index;
}
}
return - 1;
}
@Override
public Iterator<T> iterator()
{
return new ULIterator<T>();
}
private class ULIterator<T> implements Iterator<T>
{
private int currentIndex = 0;
@Override
public boolean hasNext()
{
return (currentIndex < size());
}
@Override
public T next()
{
if(hasNext())
{
return (T)nodeElements[currentIndex++].getData();
}
else
{
throw new NoSuchElementException();
}
}
}
}
// Node class
package lists.arrayLists.unorderedList;
public class Node<T>
{
private T data;
public Node(T data)
{
this.data = data;
}
public T getData()
{
return data;
}
}
1 Answer 1
Does this list interface have enough methods/behavior?
Yes, it is enough. If you want to extend it consider implementing java.util.Collection
interface.
Why do I have to type cast from next() while returning data?
When I am testing this class I have to do this Iterator itr = ((UnorderedList) ul).iterator(); why?
Those two questions are related. You need a cast to UnorderedList
since you didn't put iterator()
function in your List
interface. And cast for next()
is required since you used (UnorderedList) ul
instead of (UnorderedList<Integer>) ul
.
If MAX_SIZE
is a constant it should have final
modifier and shouldn't be changed in UnorderedList(int capacity)
. You might use nodeElements.length instead.
Node
class looks pointless, there is nothing wrong with using T[] nodeElements
or better Object[] nodeElements
, since generic arrays are tricky to construct.
You also shouldn't catch IndexOutOfBoundsException
when you can just check if index is valid before accessing it.
Explore related questions
See similar questions with these tags.
java.util.List
? \$\endgroup\$