Okay, so I am a intro programmer to java and we were assigned a project to create a functioning linked list. I am posting my DLinkedlist file to show how I created my linked list. Finally I will show the tester that is being used to make sure it is functioning properly. The exception is fine, that is what is wanted by the instructor. The problem is the "While has next" and "While has previous" outputs. Much thanks!
package project5;
import java.util.NoSuchElementException;
public class DLinkedList {
private Node first;
private Node last;
public DLinkedList() {
first = null;
last = null;
}
/**
* Adds an element to the head of the list
* @param data - the object to store at the head of the list
*/
public void addFirst(Object data){
Node newNode = new Node();
newNode.data = data; // No setter necessary
if (first != null){
newNode.next = first;
}else{
last = newNode;
}
first = newNode;
}
/**
* Gets what is stored at the beginning of the list
* @return - the data stored at the head of the list
*/
public Object getFirst(){
/*
This is the syntax for getting the "data attribute" of the object called "first"
We can do this because "data" is piublic and thus we do not need to call a getter method
*/
if (first == null){
throw new NoSuchElementException();
}
return first.data;
}
/**
* Removes the head of the list
* @return - returns data that was stored in the same node removed
*/
public Object removeFirst(){
if (first == null){
throw new NoSuchElementException();
}
Object temp = first.data;
first = first.next;
return temp;
}
/**
* Adds an element to the tail of the list
* @param data - the object to store at the tail of the list
*/
public void addLast(Object data){
Node newNode = new Node();
newNode.data = data;
if(first == null){
addFirst(data);
}else{
if (last != null){
newNode.previous = last;
last.next = newNode;
}
last = newNode;
}
}
/**
* Gets what is stored at the end of the list
* @return - the data stored at the tail of the list
*/
public Object getLast(){
/*
Ths s
*/
if (last == null){
throw new NoSuchElementException();
}
return last.data;
}
/**
* Removes the last item in the list
* @return
*/
public Object removeLast(){
if (last == null){
throw new NoSuchElementException();
}
Object temp = last.data;
last = last.previous;
return temp;
}
/**
* Checks if the Linked List contains an object
* @param other
* @return
*/
public boolean contains(Object other){
Node temp = first;
while (temp.next != null){
if(temp.data == other){
return true;
}else{
temp = temp.next;
}
}
return false;
}
/**
* Note: We return ListIterator because it is a PUBLIC interface that can be used outside fo the LinkedList class,
* whereas LinkedListIterator only exists inside LinkedList
* @return
*/
public ListIterator listIterator(){
return new LinkedListIterator();
}
class LinkedListIterator implements ListIterator{
private DLinkedList.Node position;
private DLinkedList.Node previous;
private DLinkedList.Node next;
private boolean isAfterNext;
private boolean isAfterPrevious;
public LinkedListIterator(){
position = null;
previous = null;
next = null;
isAfterNext = false;
isAfterPrevious = false;
}
@Override
public Object next() {
if (!hasNext()){
throw new NoSuchElementException();
}
// Updating previous to be at the current pos
previous = position;
// Iterator is at the beginning of the lsit
if (position == null){
position = first;
}
else{
position = position.next;
}
isAfterNext = true;
return position.data;
}
@Override
public boolean hasNext() {
if (position == null){
// Beginning of the list
return first != null;
}
else{
return position.next != null;
}
}
@Override
public void add(Object data) {
if (!isAfterNext){
throw new IllegalStateException();
}
if (position == first){
addFirst(data);
}
else{
Node newNode = new Node();
newNode.data = data;
newNode.next = position.next;
newNode.previous = position;
position.next = newNode;
position = newNode;
}
}
@Override
public Object remove() {
if (!isAfterNext){
throw new IllegalStateException();
}
Object temp;
if (position == first){
temp = removeFirst();
}
else{
temp = position.data;
previous.next = position.next;
}
position = previous;
isAfterNext = false;
return temp;
}
@Override
public Object previous() {
boolean hasBeenCalled = false;
if (!hasPrevious()){
throw new NoSuchElementException();
}
// Updating next to be at the current pos
next = position;
// Iterator is at the end of the list
if (position == null){
position = last;
}
else{
position = position.previous;
}
isAfterPrevious = true;
return position.next.data;
}
@Override
public boolean hasPrevious() {
if (position == null){
// End of the list
return first != null;
}
else{
return position.previous != null;
}
}
@Override
public void set(Object element) {
position.data = element;
}
}
/*
Node is an inner class, which means access to it is restruced to members of its outer class, i.e. LinkedList
*/
class Node{
/*
These variables don't need setters or getters because they are public, and thus can be accessed/modified by any
member of the outer class, i.e. LinkedList
*/
public Object data;
public Node next;
public Node previous;
}
}
Tester shown with expected vs actual output!
package project5;
import project5.DLinkedList;
import project5.ListIterator;
public class DLinkedListTester {
public static void main(String[] args) {
DLinkedList ages = new DLinkedList();
for(int i = 1; i <= 15; i++) {
ages.addFirst(i);
}
for(int i = 16; i <= 30; i++) {
ages.addLast(i);
}
System.out.println("Remove First Expected: 15");
System.out.println("Output: "+ages.removeFirst() + "\n");
System.out.println("Remove Last Expected: 30");
System.out.println("Output: "+ages.removeLast() + "\n");
System.out.println("Get First Expected: 14");
System.out.println("Output: "+ages.getFirst() + "\n");
System.out.println("Get Last Expected: 29");
System.out.println("Output: "+ages.getLast() + "\n");
System.out.println("Contains 10 Expected: true");
System.out.println("Output: " + ages.contains(10) + "\n");
System.out.println("Contains 100 Expected: false");
System.out.println("Output: " + ages.contains("100") + "\n");
ListIterator iter = ages.listIterator();
System.out.print("While has next Expected: 14 13 12 11 10 9 8 7 6 5 4 3 2 1 16 17 18 19 20 21 22 23 24 25 26 27 28 29 \nOutput: ");
while(iter.hasNext()) {
System.out.print(iter.next() + " ");
}
System.out.println("\n");
System.out.print("While has previous Expected: 29 28 27 26 25 24 23 22 21 20 19 18 17 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 \nOutput: ");
while(iter.hasPrevious()) {
System.out.print(iter.previous() + " ");
}
iter = ages.listIterator();
iter.next(); //14 | 13 12 11 10 ...
iter.next(); //14 13 | 12 11 10 ...
iter.add("12.5"); //14 13 12.5 | 12 11 10 ...
iter.next(); //14 13 12.5 12 | 11 10 ...
System.out.println("\n\nRemove Expected: 12");
System.out.println("Output: " + iter.remove() + "\n");
iter.previous(); //14 13 | 12.5 11 10 ...
iter.previous(); //14 | 13 12.5 11 10 ...
iter.remove(); //14 | 12.5 11 10 ...
while(iter.hasNext()) {
iter.next();
}
iter.previous();
iter.set("100");
System.out.print("\nWhile has next Expected: 14 12.5 11 10 9 8 7 6 5 4 3 2 1 16 17 18 19 20 21 22 23 24 25 26 27 28 100 \nOutput: ");
iter = ages.listIterator();
while(iter.hasNext()) {
System.out.print(iter.next() + " ");
}
}
}
Console Output!
Remove First Expected: 15
Output: 15
Remove Last Expected: 30
Output: 30
Get First Expected: 14
Output: 14
Get Last Expected: 29
Output: 29
Contains 10 Expected: true
Output: true
Contains 100 Expected: false
Output: false
While has next Expected: 14 13 12 11 10 9 8 7 6 5 4 3 2 1 16 17 18 19 20 21
22 23 24 25 26 27 28 29
Output: 14 13 12 11 10 9 8 7 6 5 4 3 2 1 16 17 18 19 20 21 22 23 24 25 26 27
28 29 30
While has previous Expected: 29 28 27 26 25 24 23 22 21 20 19 18 17 16 1 2 3
4 5 6 7 8 9 10 11 12 13 14
Output: 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Remove Expected: 12
Output: 12
Exception in thread "main" java.util.NoSuchElementException
at project5.DLinkedList$LinkedListIterator.previous(DLinkedList.java:224)
at project5.DLinkedListTester.main(DLinkedListTester.java:59)