Follow-up to this question as recommended.
Can this code be improved from an OOP paradigm perspective?
package JavaCollections;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* Dlist using sentinel node
*
* @author mohet01
*
* @param <T>
*/
public class DblyLinkList<T> implements Iterable<T>{
/**
* DListNode is a node in a DblyLinkList
*
* @author mohet01
*
*/
private class DListNode<T> {
/**
* item references the item stored in the current node. prev references the
* previous node in the DList. next references the next node in the DList.
*
*
*/
T item;
DListNode<T> prev;
DListNode<T> next;
/**
* DListNode() constructor.
*/
DListNode() {
this(null);
}
DListNode(T item) {
this.item = item;
this.prev = null;
this.next = null;
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
}
private class Itr implements Iterator<T>{
private int currentPosition = 0;
private int lastRet = -1;
@Override
public boolean hasNext() {
return currentPosition != size();
}
@Override
public T next() throws NoSuchElementException {
if (currentPosition > size()){
throw new NoSuchElementException();
}
T next = get(currentPosition);
lastRet = currentPosition;
currentPosition++;
return next;
}
@Override
public void remove() throws NoSuchElementException{
if(lastRet < 0 ){
throw new IllegalStateException();
}else{
DblyLinkList.this.remove(currentPosition);
lastRet = -1;
}
}
}
/**
* head references the sentinel node.
*
* Being sentinel as part of implementation detail, will avoid null checks,
* while performing mutable operations on list.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
*
*/
private DListNode<T> head;
private int size;
/*
*
*
* DblyLinkList invariants:
* 1) head != null.
* 2) For any DListNode x in a DblyLinkList, x.next != null.
* 3) For any DListNode x in a DblyLinkList, x.prev != null.
* 4) For any DListNode x in a DblyLinkList, if x.next == y, then y.prev == x.
* 5) For any DListNode x in a DblyLinkList, if x.prev == y, then y.next == x.
* 6) size is the number of DListNode's, NOT COUNTING the sentinel (referenced
* by "head"), that can be accessed from the sentinel by a sequence of "next" references.
*/
/**
* DblyLinkList() constructor for an empty DblyLinkList.
*/
public DblyLinkList() {
this.head = new DListNode<T>();
this.head.next = this.head;
this.head.prev = this.head;
}
/**
* DblyLinkList() constructor for a one-node DblyLinkList.
*/
public DblyLinkList(T item) {
this.head = new DListNode<T>();
this.insertFront(item);
}
/**
* Return the size of the linked list
* @return
*/
public int size(){
return size;
}
void remove(int index) throws NoSuchElementException{
if(index > size()){
throw new NoSuchElementException();
}
DListNode<T> node;
for (node = head; index-- > 0; node = node.next);
node.item = null;
node.prev.next = node.next;
node.next.prev = node.prev;
}
/**
* Inserts a non-sentinel node at front of the list.
*
* @param item
*/
public void insertFront(T item){
DListNode<T> node = new DListNode<>(item);
node.next = head.next;
node.prev = head;
node.next.prev = node;
head.next = node;
this.size++;
}
/**
* Remove first non-sentinel node from the list.
* Do not require size check before remove operation
*
*/
public void removeFront(){
head.next.next.prev = head;
head.next = head.next.next;
if(this.size() > 0){
this.size--;
}
}
public T get(int index) throws NoSuchElementException{
if (index > size()) throw new NoSuchElementException();
DListNode<T> node;
for (node = head; index-- > 0; node = node.next);
return node.item;
}
@Override
public Iterator<T> iterator() {
return new Itr();
}
}