Solved

JAVA, generics, Iterator, LinkedLIst

Posted on 2014-02-23
2
435 Views
Last Modified: 2014-02-23
Subsequent to an earlier question, I'm attaching my DoublyLinkedList implementation. It probably has a few more methods than it needs, but that is OK I'm not concerned about that.
http://www.experts-exchange.com/Programming/Languages/Java/Q_28371713.html
The problem I'm having is that I'm not able to properly utilize the for-in loop in code that uses my (very home grown) DoublyLinkedList.

I'm having to use Object, and then create a new Object and cast it to my type, like this:

for( DoublyLinkedList<Entry<K, V>> bucket : oldTable ){
            if( bucket != null ){
                for(Object entry : bucket){
                    Entry<K,V> e = (Entry<K,V>) entry;
                    put((K) e.getKey(), (V) e.getValue() );
                }
            }
        }

Open in new window


That seems terribly wasteful to me, and it just looks "wrong". I *should* be able to do this:

for( DoublyLinkedList<Entry<K, V>> bucket : oldTable ){
            if( bucket != null ){
                for(Entry<K,V> entry : bucket){
                    put((K) entry.getKey(), (V) entry.getValue() );
                }
            }
        }

Open in new window


Here is my linked list and my linked list interface:

import java.util.Iterator;

public class DoublyLinkedList<E> implements DoublyLinkedListInt<E>, Iterable{
	private DNode<E> head;
	private DNode<E> tail;
	private DNode<E> current;
	private int size = 0;

	public DoublyLinkedList() {
		this.head = null;
		this.tail = null;
		this.current = null;
	}
	/* this was being used for a version of Iterator class, 
	* which I have since deleted, but leaving this in for now
	*/
	public DNode<E> getFirstNode() throws java.util.NoSuchElementException {
		if (this.size == 0) {
			throw new java.util.NoSuchElementException();
		}
		this.current = this.head;
		return this.head;
	}
	@Override
	public E getFirst() throws java.util.NoSuchElementException {
		if (this.size == 0) {
			throw new java.util.NoSuchElementException();
		}
		this.current = this.head;
		return this.head.element;
	}
	@Override
	public E getLast() throws java.util.NoSuchElementException {
		if (this.size == 0) {
			throw new java.util.NoSuchElementException();
		}
		this.current = this.tail;
		return this.tail.element;
	}
	@Override
	public E getNext() throws java.util.NoSuchElementException {
		if (this.size == 0 || this.current == null) {
			throw new java.util.NoSuchElementException();
		}
		this.current = this.current.next;
		if (this.current == null) {
			throw new java.util.NoSuchElementException();
		}
		E element = this.current.element;
		return element;
	}
	public DNode<E> getNextNode() throws java.util.NoSuchElementException {
		if (this.size == 0 || this.current == null) {
			throw new java.util.NoSuchElementException();
		}
		this.current = this.current.next;
		if (this.current == null) {
			throw new java.util.NoSuchElementException();
		}
		return this.current;
	}
	public boolean hasNext(){
		if (this.size == 0 || this.current == null) {
			return false;
		}
		if(this.current.next == null){
			return false;
		}
		return true;
	}
	@Override
	public E getPrevious() {
		if (this.size == 0 || this.current == null) {
			throw new java.util.NoSuchElementException();
		}
		this.current = this.current.previous;

		if (this.current == null) {
			throw new java.util.NoSuchElementException();
		}
		E element = this.current.element;
		return element;
	}
	@Override
	public E getCurrent() throws java.util.NoSuchElementException {
		if (this.size == 0 || this.current == null) {
			throw new java.util.NoSuchElementException();
		}
		E element = this.current.element;
		return element;
	}
	@Override 
	public void addFirst(E element) {
		DNode<E> node = new DNode<E>(element);
		if(this.head != null){
			node.next = this.head;
			node.previous = null;
			this.head.previous = node;
			this.head = node;
		}else{
			node.next = null;
			node.previous = null;
			this.tail = node;
			this.head = node;
		}
		this.current = node;
		this.size++;
	}
	@Override 
	public void addLast(E element) {
		if (this.size == 0) { // or, check: this.tail == null
			addFirst(element);
		} else {
			DNode<E> node = new DNode<E>(element);
			node.previous = this.tail;
			node.next = null;
			this.tail.next = node;
			this.tail = node;
			this.current = node;
			this.size++;
		}
	}
	@Override 
	public void addNext(E element) {
		if (this.size == 0) {
			addFirst(element);
		}else if(this.current == this.tail){
			addLast(element);
		}else{
			DNode<E> node = new DNode<E>(element);
			node.previous = this.current;
			node.next = this.current.next;
			this.current.next.previous = node;
			this.current.next = node;
			this.current = node;
			this.size++;
		}
	}
	@Override
	public void addPrevious(E element) {
		if(this.current == this.head){
			throw new java.util.NoSuchElementException();
		}else{
			DNode<E> node = new DNode<E>(element);
			node.next = this.current;
			node.previous = this.current.previous;
			this.current.previous.next = node;
			this.current.previous = node;
			this.current = node;
			this.size++;
		}
	}
	@Override 
	public void removeFirst() throws java.util.NoSuchElementException {
		if (this.size == 0) {
			throw new java.util.NoSuchElementException();
		}
		if(this.size == 1){
			this.current = null;
			this.head = null;
		}else{
			this.current = this.head.next;
			this.head.next.previous = null;
		}
		DNode<E> node = this.head;
		this.head = node.next;
		node.reset();
		this.size--;
		if(this.size == 1){
			this.tail = this.current;
		}
	} 
	@Override
	public void removeLast() throws java.util.NoSuchElementException {
		if (this.size == 0) {
			throw new java.util.NoSuchElementException();
		}
		if (size == 1) {
			this.current = null;
			this.head = null;
		} else {
			this.current = this.tail.previous;
			this.tail.previous.next = null;
		}
		DNode<E> node = this.tail;
		this.tail = node.previous;
		node.reset();
		this.size--;
	}
	@Override
	public void removeNext() throws java.util.NoSuchElementException {
		if (this.size == 0 || this.current == null || this.current.next == null) {
			this.current = null;
			throw new java.util.NoSuchElementException();
		}
		DNode<E> node = this.current.next;
		this.current.next = node.next;
		if (this.current.next != null) {
			this.current.next.previous = this.current;
		} else {
			this.tail = this.current;
			//this.current = null;
		}
		node.reset();
		this.size--;
	}
	@Override
	public void removePrevious() throws java.util.NoSuchElementException {
		if (this.size == 0 || this.current == null || this.current.previous == null) {
			this.current = null;
			throw new java.util.NoSuchElementException();
		}
		DNode<E> node = this.current.previous;
		this.current.previous = node.previous;
		if (this.current.previous != null) {
			this.current.previous.next = this.current;
		} else {
			this.head = this.current;
			//this.current = null;
		}
		node.reset();
		this.size--;
	}

	/** Removes the current item
	*	sets the next item to current
	*/
	@Override
	public void removeCurrent() throws java.util.NoSuchElementException {
		if (this.size == 0 || this.current == null) {
			this.current = null;
			throw new java.util.NoSuchElementException();
		}
		if(this.current.next == null){
			removeLast();
		}else if (this.current.previous == null) {
			removeFirst();
		} else {
			DNode<E> node = this.current;
			this.current.next.previous = this.current.previous;
			this.current.previous.next = this.current.next;
			this.current = this.current.next;
			node.reset();
			this.size--;
		}
	}
	@Override
	public int getSize() {
		return this.size;
	}
	@Override
	public boolean isEmpty() {
		return this.size == 0;
	}
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("<");
		DNode<E> node = head;
		while (node != null) {
			if (node.element != null) {
				sb.append(", "+node.element.toString());
			} else {
				sb.append("null ");
			}
			node = node.next;
		}
		if(sb.length()>=2){sb.deleteCharAt(1);};
		sb.append(" >");
		return sb.toString();
	}
	public boolean contains(E el){
		DNode<E> node = head;
		while (node != null) {
			if (node.element != null) {
				 if(el.equals(node.element)){return true;};
			}
			node = node.next;
		}
		return false;
	}
	public class DNode<T> {
		public T element;
		public DNode<T> next = null;
		public DNode<T> previous = null;
		public DNode(T element) {
			this.element = element;
		}
		public void reset() {
			this.element = null;
			this.next = null;
			this.previous = null;
		}
	}
	
	
	
/*******************************************************
 *
 *  The Iterator class
 *
********************************************************/
   @Override
   public Iterator<E> iterator(){
      return new DoublyLinkedListIterator();
   }

   private class DoublyLinkedListIterator  implements Iterator<E> {
      private DNode<E> nextNode;

      public DoublyLinkedListIterator(){
         nextNode = head;
      }
      @Override
      public boolean hasNext(){
         return nextNode != null;
      }
      @Override
      public E next(){
         if (!hasNext()) { return null; }
         E element = nextNode.element;
         nextNode = nextNode.next;
         return element;
      }
      @Override
        public void remove() {
        	throw new UnsupportedOperationException();
        }
   }

/* another version of iterator ******************************* /	
    @Override
	public Iterator<E> iterator() {
		return new Iter<E>(this);
	}
  	private class Iter<T> implements Iterator<E> {
        private int count = 0;
        private DoublyLinkedList<E> dll;
        public Iter(DoublyLinkedList<E> dll) {
           count = 0;
           this.dll = dll;
           dll.current = dll.head;
        }
        @Override
        public boolean hasNext() {
            return count < this.dll.getSize();
        }
        @Override
        public E next() {
			count++;
			E element = this.dll.current.element;
			this.dll.current = this.dll.current.next;
			return element;
        }
        @Override
        public void remove() {
        	throw new UnsupportedOperationException();
        }
    }
/**********************************************************/
}

Open in new window

public interface DoublyLinkedListInt<E>{
	E getFirst();
	E getLast();
	E getNext();
	E getPrevious();
	E getCurrent();
	void addFirst(E element);
	void addLast(E element);
	void addNext(E element);
	void addPrevious(E element);
	void removeFirst();
	void removeLast();
	void removeNext();
	void removePrevious();
	void removeCurrent();
	int getSize();
	boolean isEmpty();
}

Open in new window


Thanks,
Koza
0
Comment
Question by:Kyle Hamilton
2 Comments
 
LVL 14

Accepted Solution

by:
CPColin earned 500 total points
ID: 39881463
Try making your DoublyLinkedListInt interface extend Iterable<E>. That Iterable interface is also generic, so it needs a type parameter.
0
 
LVL 25

Author Closing Comment

by:Kyle Hamilton
ID: 39881494
this fixes it:

public class DoublyLinkedList<E> implements DoublyLinkedListInt<E>, Iterable<E>{...}

Thanks CPColin :)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now