Java BST iterator using an array - java

Class definition for Binary Search Tree in Java:
public class BST<E extends Comparable<E>> implements Iterable<E>, Cloneable
public Iterator<E> iterator() {
return new BSTInOrderIterator();
}
private class BSTInOrderIterator implements Iterator<E> {
private int sortedArrayFillerIndex;
private final E[] sortedArray;
private int ptr;
public BSTInOrderIterator() {
sortedArrayFillerIndex = 0;
sortedArray = (E[]) (new Object[size()]);
inOrder(root);
ptr = 0;
}
private void inOrder(Node x) {
if (x == null) return;
inOrder(x.left);
sortedArray[sortedArrayFillerIndex++] = x.value;
inOrder(x.right);
}
#Override
public boolean hasNext() {
return ptr < size();
}
#Override
public E next() {
return sortedArray[ptr++];
}
}
In the iterator, I first build a sorted array through an inorder traversal of my BST.
However, I get class cast exception in the constructor of the BST iterator. How do I handle that?

The issue is in the line sortedArray = (E[]) (new Object[size()]);. You cannot initialize a generic array like this. To initialize the sortedArray try below.
sortedArray =(E[]) Array.newInstance(clazz, size())
Be aware that you need to provide the class of the required object as the clazz
See the answers for this question for more details. How to create a generic array in Java?

Related

Implementing iterator to an ArrayList

I am having trouble with my code to add iterator support to ArrayList
this is the class i create to implement Iterator
class MyArrayListIterator<E> implements Iterator<E> {
private E[] list = null;
private int currentIndex = 0;
#Override
public boolean hasNext() {
if (currentIndex < list.length) {
return true;
} else {
return false;
}
}
#Override
public E next(){
return list[currentIndex++];
}
}
This must include, which i think i did correct
"list" of type MyArrayList
"currentIndex" of type int, initially at zero
This is my main method for testing
public static void main(String[] args) throws Exception {
MyList<String> names = new MyArrayList<>();
names.add("Steve");
names.add("Frank");
names.add("Heather");
names.add("Chris");
names.add("Oliver");
for (String string : names) { // error at names Can only iterate over an array or an instance of java.lang.Iterable
System.out.println(string);
}
}
}
In the myArrayList i have added as the requirement is Make MyArrayList implement the Iterable interface by adding the iterator() method, which should return an instance of MyArrayListIterator.
public Iterator<E> iterator() {
return new MyArrayListIterator();
}
Please let me know what I am doing wrong.
As already mentioned in the comments, your problem is that you read from list in MyArrayListIterator without initializing it. This causes a NullPointerException.
You can fix this in two different ways:
Make MyArrayListIterator a non-static nested (they are also called inner classes) class of MyArrayList.
By doing so, you get access to all fields of the outer-class, which in this case is MyArrayList. For example, see this code snippet:
public class MyArrayList<E> implements MyList<E> {
private Object[] list = new Object[10];
private int size = 0;
public Iterator<E> iterator(){
return new MyArrayListIterator<>();
}
// more of your implementation...
// This is the inner class
private class MyArrayListIterator<T> implements Iterator<T> {
private int currentIndex = 0;
#Override
public boolean hasNext() {
// Since this is a inner class, we have access to the
// "list" field defined by MyArrayList.
return currentIndex < list.length;
}
#Override
public T next() {
// Since this is a inner class, we have access to the
// "list" field defined by MyArrayList.
return (T) list[currentIndex++];
}
}
}
Make MyArrayListIterator a static nested class or a separate class.
In this case, you don't have access to the fields defined in MyArrayList, which means you have to provide them yourself. This can be done using the constructor.
public class MyArrayList<E> implements MyList<E> {
private Object[] list = new Object[10];
private int size = 0;
public Iterator<E> iterator(){
return new MyArrayListIterator<>((E[])list);
}
// More of your list implementation
// This is a static inner class, which means we do not have access to
// the fields of the outer class.
private static class MyArrayListIterator<T> implements Iterator<T> {
private final T[] elements;
private int currentIndex = 0;
public MyArrayListIterator(T[] elements) {
this.elements = elements;
}
#Override
public boolean hasNext() {
// Since we got the elements as constructor argument, they are not
// null (assuming you did not call it with null as parameter).
return currentIndex < elements.length;
}
#Override
public T next() {
// Since we got the elements as constructor argument, they are not
// null (assuming you did not call it with null as parameter).
return elements[currentIndex++];
}
}
}
For more information on nested classes, see this tutorial by Oracle on nested classes.

Is it possible to create a generic class with empty constructor in Java

Is it possible to create a generic class with empty constructor?
To something like this:
public class ArrayListGeneric1<T> {
private int capacity;
private int size;
private T [] array;
public ArrayListGeneric1() {
capacity = 1;
array = Array.newInstance(T.getClass(), capacity); //Cannot get the class for T
size = 0;
}
}
I can only find solutions where we need to pass an element
Is it possible to create a generic class with empty constructor?
Sure, do it without a generic array, just like ArrayList does:
public class ArrayListGeneric1<T> {
private int capacity = 1;
private int size = 0;
private Object[] array = new Object[capacity];
public ArrayListGeneric1() {}
public T get(int i) {
return (T) array[i];
}
public void set(int i, T element) {
array[i] = element;
}
}
You can actually do it with a generic array, if you make the type abstract, and subclass it when you create an instance:
public abstract class ArrayListGeneric1<T> {
private int capacity = 1;
private int size = 0;
private T[] array = Array.newInstance(getElementType(), capacity);
public ArrayListGeneric1() {}
Class<?> getElementType() {
ParameterizedType pt = (ParameterizedType) getClass().getGenericSuperclass();
Type[] typeArgs = pt.getActualTypeArguments();
// Will fail if it's not a class type.
return (Class<?>) typeArgs[0];
}
// ...
}
Then:
ArrayListGeneric1<String> list = new ArrayListGeneric1<String>() {}
Demo: https://ideone.com/fgJ5dl
Yes. Given below is an example from Java OOTB class:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private int size;
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this(10);
}
...
...
...
}
It's not a problem. ArrayList is a generic class with no-args constructor:
List<Integer> a = new ArrayList<>();
List b = new ArrayList<>();
var c = new ArrayList<>();
You can find the exemplary implementation here.

linked list iterator inner class-java

I am writing an iterator inner class that iterates through a list. Besides the remove method, I believe I have implemented all the methods of iterator correctly but I get an error saying "Bound mismatch: The type E is not a valid substitute for the bounded parameter > of the type List.Node". I believe this has to with having Node> implements Iterable at the top of my code but I do not want to change that if unneeded. Any possible suggestions on what I should do?
public class List<T extends Comparable<L>> implements Iterable<L> {
private class Node<N extends Comparable<N>> {
private N data;
private Node<N> next;
}
protected Node<L> head;
public Iterator<L> iterator() {
return new ListIterator<L>();
}
public class ListIterator<E extends Comparable<E>> implements Iterator<E> {
private Node<E> N = (Node<E>) head; //"Bound mismatch: The type E is not a valid substitute for the bounded parameter <D extends Comparable<D>> of the type List<T>.Node<D>"
public boolean hasNext() {
return (N.next != null);
}
public E next() {
if (!hasNext())
throw new NoSuchElementException();
else {
N = N.next;
return N.data;
}
}
public void remove() {
}
}
}
You should reduce the number of generic types. Because the inner classes know the generic type of their parent class, you should simplify the Node and ListIterator class:
public class List<L extends Comparable<L>> implements Iterable<L> {
private class Node {
private L data;
private Node next;
}
protected Node head;
public Iterator<L> iterator() {
return new ListIterator();
}
public class ListIterator implements Iterator<L> {
private Node N = head;
public boolean hasNext() {
return (N.next != null);
}
public L next() {
if (!hasNext())
throw new NoSuchElementException();
else {
N = N.next;
return N.data;
}
}
public void remove() {
}
}
}
The type parameter N is declared as
N extends Comparable<N>
ie. it has bounds. It must be Comparable to itself.
The type parameter E is declared as
E
ie. it has no bounds. It can be any type, but not necessarily a type that is Comparable to itself.
Therefore, you can't use E where an N is expected. Consider adding the same bounds as N to E.

Iterate over array or instance of java.lang.Iterable - Missing common sense solution?

I am trying to implement a Tree structure using a doubly linked list (called LinkedTree). With that said, when using my for-each loops, I end up getting the same repeated error: Can only iterate over an array or an instance of java.lang.Iterable. I've looked up some similar questions online but I can't seem to locate the problem. I know in order to iterator, you must have instances of iterable but isn't positions as well as children() both instances of iterable? I've included both methods with the errors, my children method, and my own implementation of iterable and iterator. Thanks in advance for the assistance.
public Iterator<E> iterator() {
Iterable<Position<E>> positions = positions();
PositionalList<E> elements = new NodePositionalList<E>();
for (Position<E> p: positions) // ERROR # positions
elements.addLast(p.element());
return elements.iterator();
}
private void preOrderPositions(Position<E> v, PositionalList<Position<E>> pos)
throws InvalidPositionException {
pos.addLast(v);
for (Position<E> w : children(v)) //ERROR # children (v)
preOrderPositions(w, pos);
}
Children Method
public Iterable<Position<E>> children(Position<E> v)
throws InvalidPositionException {
TreePosition <E> p = checkPosition(v);
if (isExternal(v))
throw new InvalidPositionException("");
return p.getChildren();
Iterator
public interface Iterator<E> {
public boolean hasNext();
public E next();
public void remove();
}
Iterable
public interface Iterable <E> {
public Iterator<E> iterator();
public Iterable<Position<E>> positions();
}
ElementIterator (my iterator implementation)
public class ElementIterator<E> implements Iterator <E> {
private PositionalList <E> list;
private Position <E> cursor;
public ElementIterator (PositionalList <E> L){
list = L;
cursor = (list.isEmpty())? null: list.first();
}
public boolean hasNext() {
return (cursor != null);
}
public E next(){
E toReturn = cursor.element();
cursor = (cursor == list.last())? null: list.next(cursor);
return toReturn;
}
public void remove(){
throw new UnsupportedOperationException();
}
}
EDIT: I converted the for-each loop into a while loop as shown below....
protected void preOrderPositions(Position<E> v,
PositionalList<Position<E>> pos) throws InvalidPositionException {
pos.addLast(v);
Iterator<Position<E>> iter = children(v).iterator();
while (iter.hasNext()) {
Position<E> w = iter.next();
preOrderPositions(w, pos);
}
}
You can only iterate over a class that implements java.lang.Iterable. You however try to iterate over your custom iterable interface. That doesnt work:
public interface Iterable <E> {
public Iterator<E> iterator();
public Iterable<Position<E>> positions(); // <- your custom Iterable class is returned here, NOT java.lang.Iterable
}
If you want to iterate using your iterable class, extend java.lang.Iterable
public interface Iterable <E> extends java.lang.Iterable<E>
HINT: Do not write classes / interfaces that have the same name as anything in the java.lang package.

How can I create an iterable generic class that runs on two generic types?

How can I create an iterable generic class that runs on two generic types?
That is, if I have a class called:
public class PriorityQueue<K,V> {}
how can I implement Iterable if I am unable to use implements Iterable<K,V>? Eclipse is giving an error saying:
Incorrect number of arguments for type Iterable; it cannot be parameterized with arguments
I must be misunderstanding how to implement my own iterable collection.
And on this subject: Do I want to make my priorityqueue iterable, or do I make my entries that the queue stores iterable?
Edit:
For my homework assignment, I have to implement the PriorityQueue ADT in a linked list fashion. I've implemented all the methods save for one -- min(). The way I'm thinking of doing it is iterating over all the Entry objects stored in my list by making a private entries() method. But I have no idea how to approach this.
I have right now a link to the head of the linked list and a link to the tail. How can I make said entries() method so that I can return an Iterable object of the entries?
Here's my Entry<K,V> object:
public class Entry<K,V> implements Comparable {
private V _value;
private K _key;
private Entry<K,V> _prev;
private Entry<K,V> _next;
public Entry(K key, V value) {
this._value = value;
this._key = key;
this._prev = null;
this._next = null;
}
public V getValue() {
return this._value;
}
public K getKey() {
return this._key;
}
public Entry<K,V> getNext() {
return _next;
}
public void setNext(Entry<K,V> link) {
this._next = link;
}
public Entry<K,V> getPrev() {
return _prev;
}
public void setPrev(Entry<K,V> link) {
this._prev = link;
}
#Override
public int compareTo(Object arg0) {
if (arg0 instanceof Entry<?,?>) {
}
return 0;
}
}
And here's my PriorityQueue<K,V> so far:
public class PriorityQueue<K,V> implements Iterable<K>{
private Entry<K,V> _head;
private Entry<K,V> _tail;
private int _size;
public PriorityQueue() {
this._head = null;
this._tail = null;
this._size = 0;
}
public int size() {
return _size;
}
public boolean isEmpty() {
return (size() == 0);
}
public Entry<K,V> min() {
}
public Entry<K,V> insert(K k, V x) {
Entry<K,V> temp = new Entry<K,V>(k,x);
if (_tail == null) {
_tail = temp;
_head = temp;
}
else {
_tail.setNext(temp);
temp.setPrev(_tail);
_tail = temp;
}
return temp;
}
public Entry<K,V> removeMin() {
Entry<K,V> smallest = min();
smallest.getPrev().setNext(smallest.getNext());
smallest.getNext().setPrev(smallest.getPrev());
return smallest;
}
#Override
public Iterator<K> iterator() {
// TODO Auto-generated method stub
return null;
}
}
You have to use a wrapper class for the returned Iterable object. In your case I assume it to be type Entry. So as an example, your code should look like:
public class PriorityQueue<K, V> implements Iterable<Entry<K, V>> {
}
Of course, you can always create a custom wrapper.
Iterable means you can iterate over objects of its type. It accepts one type parameter.
From the documentation:
public interface Iterable
Implementing this interface allows an object to be the target of the "foreach" statement.
If you want it to be Iterable over your keys your class should implement Iterable<K>.
If you want it to be Iterable over your values your class should implement Iterable<V>.
Here is a blog post about implementing Iterable.
Normally, you want to make the entries that the queue stores iterable, you also might want to figure out in what order.
If you're wandering about implement a Priority Queue you might also want to take a look at Java's own PriorityQueue implementation and follow that.

Categories