Solved

JAVA, generics, Iterator, LinkedLIst

Posted on 2014-02-23
2
443 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

What Is Transaction Monitoring and who needs it?

Synthetic Transaction Monitoring that you need for the day to day, which ensures your business website keeps running optimally, and that there is no downtime to impact your customer experience.

Question has a verified solution.

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

Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

691 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