Java- Error concerning Generics - java

I have a class & and inner class that work together to make a linked list. The data held by the nodes, is Generic, and I somewhere along the line of my code I screwed up involving generics but I don't know where. I get 5 errors, the first one says "type LinkedList does not take parameters" which i think is weird because LinkedList is just an interface that i'm implementing. The rest of them are phrased "Object cannot be converted to E". I marked where they're occurring. I figured my assignment was right I don't know what's wrong. If you'd like me to post the interface LinkedList let me know.
public class SinglyLinkedList<E> implements LinkedList<E> {
private Node head;
private Node tail;
private int size;
public SinglyLinkedList(){
this.head = null;
this.tail = null;
this.size = 0;
}
public E get(int index) {
//Hold the data of the cur node
//and keep iterating until you hit the
//right index
int hit = 0;
Node pos = this.head;
E found = this.head.data;//////ERROR HERE
while (hit < index) {
pos = pos.next;
found = pos.data;//////ERROR HERE
hit++;
}
return found;
}
public void add (E data) {
Node last = new Node(data, null);
//If the list is empty.
if (this.head == null) {
this.head = last;
}
//Make the cur tail's next the new node
//and set the new node as the new tail.
this.tail.next = last;
this.tail = last;
this.size++;
}
public boolean add(int index, E data) {
//Cannot add if index is not valid
if ((index >= this.size) || (index < 0) ) {
return false;
}
//If index is 0, add at beginning
Node insert = new Node(data, null);
if (index == 0) {
insert.next = this.head;
this.head = insert;
this.size++;
return true;
} else {
//Else, go until you reach desired index then
//Set whatever was at that index to the new Node's
//next value.
int hit = 1;
Node cur = this.head;
while (hit < index) {
cur = cur.next;
hit++;
}
insert.next = cur;
this.size++;
return false;
}
}
public void addAll(Collection<? extends E> c) {
for (E item: c) {
this.add(item);
}
}
public boolean contains(E data) {
int hit = 0;
Node cur = this.head;
Node move;
while (hit < this.size) {
if (data.equals(cur.data)) {
return true;
} else {
move = cur.next;
cur = move;
}
}
return false;
}
public boolean containsAll(Collection<? extends E> c) {
for (E item: c) {
if (!(this.contains(item))) {
return false;
}
}
return true;
}
public boolean remove(E data) {
Node prev = this.head;
Node cur = this.head.next;
int hit = 1;
if (!(this.contains(data))) {
return false;
} else if (data.equals(head.data)) {
this.head = cur;
return true;
this.size--;
}
while (hit < this.size) {
if (data.equals(cur.data)) {
prev.next = cur.next;
return true;
this.size--;
}
hit++;
}
}
public E remove(int index) {
int hit = 1;
E data;
Node prev = this.head;
Node cur = this.head.next;
if (index == 0) {
data = head.data; //////ERROR HERE
this.head = cur;
return data;
this.size--;
} else {
while (hit < this.size) {
if ( hit == index) {
data = cur.data; //////ERROR HERE
prev.next = cur.next;
return data;
this.size--;
} else {
prev = cur;
cur = prev.next;
hit++;
}
}
}
}
public boolean removeAll(Collection<? extends E> c) {
int prevSize = this.size;
for (E item: c) {
remove(item);
}
return (prevSize < this.size);
}
public int size() {
return this.size;
}
public boolean isEmpty() {
return (this.head == null);
}
public void clear() {
this.head = null;
this.tail = null;
size = 0;
}
private class Node<E> {
private E data;
private Node next;
private Node(E data, Node next) {
this.data = data;
this.next = next;
}
}
}
This is the interface class
/**
* The LinkedList interface defines a set of standard operations that are
* typically associated with linked list, such as adding, removing, and checking
* to see if the list contains an item.
*
* Note that while your linked list implementation should make use of a Node
* class, the methods below take in and return instances of the generic type,
* not the nodes themselves.
*
* #author Justin Nieto
* #version 1.1
* #param <E> the type of the elements to store in the linked list
*/
public interface LinkedList<E> {
/**
* Returns the element in the linked list at the specified index.
* Does not change the contents of the list in any way. If the given
* index is negative or greater than the maximum possible index, returns
* null.
*
* #param index of element to be retrieved
* #return the element at the given index or null if index out of bounds
*/
E get(int index);
/**
* Adds the specified piece of data to the end of the linked list.
* This method should execute in O(1) (constant) time. This means that
* you should not iterate over the whole list to add the item to the end
* (we will check for this).
*
* #param data the object to be added to the linked list
*/
void add(E data);
/**
* Adds given piece of data to the linked list at the given index.
* All items that were originally at the index or after the index should
* be shifted down by one. If the index specified is not valid, returns
* false. Otherwise, returns true.
*
* If the index specified is 0 or if it is one larger than the maximum
* current index (ie if index is equal to the size of the linked list),
* then this method should execute in O(1) (constant) time. This means that
* you should not iterate over the entire list to add the element, as it
* is unnecessary to do so.
*
* #param index the index at which to add the item
* #param data the item to be added to te linked list
* #return true if the data could be added at the given index
*/
boolean add(int index, E data);
/**
* Adds each element in the Collection to the end of the linked list.
*
* #param c the collection of items to add to the end of the linked list
*/
void addAll(Collection<? extends E> c);
/**
* Determines whether or not the given piece of data is in the linked list.
*
* #param data the item to check
* #return true if the linked list contains the item, false otherwise
*/
boolean contains(E data);
/**
* Determines whether or not every element of the given Collection is
* in the linked list.
*
* #param c the Collection of elements to check
* #return true if list contains every element in the Collection
*/
boolean containsAll(Collection<? extends E> c);
/**
* Finds the first element of the list equal to the given piece of data
* and removes it from the list. Returns false if the given piece of data
* is not in the list and therefore cannot be removed.
*
* #param data the piece of data to be removed from the list
* #return true if the item was removed, false if list does not contain it
*/
boolean remove(E data);
/**
* Removes and returns the item in the list at the given index.
* All items at indices after the given index are shifted down by one.
*
* #param index the index of the item to remove from the linked list
* #return the removed item
*/
E remove(int index);
/**
* Removes each element in the given collection from the linked list.
*
* #param c the Collection of items to remove
* #return true if each element in the Collection was removed.
*/
boolean removeAll(Collection<? extends E> c);
/**
* Returns the number of elements in the linked list. This method
* should execute in O(1) (constant) time. This means that you should not
* iterate over the entire list to count the number of items, but rather
* you should maintain a size variable that you can just return here.
*
* #return the number of elements in the linked list
*/
int size();
/**
* Returns true if the linked list has no elements.
*
* #return true if the list is empty, false otherwise
*/
boolean isEmpty();
/**
* Removes all elements from the list. After calling this method,
* the isEmpty method should return true.
*/
void clear();
}

Node is an inner class of SinglyLinkedList, so it already shares the type parameter E. Therefore you could make Node a non-generic class.
private class Node {
private E data;
private Node next;
private Node(E data, Node next) {
this.data = data;
this.next = next;
}
}
That removes many of the problems, because before Node was a generic class and you were using Node without a type parameter.
An alternative solution is to make Node a static nested class. This means that an instance of Node does not belong to an instance of SinglyLinkedList. Because of this, a static version of Node would need its own type parameter.
private static class Node<E> {
private E data;
private Node<E> next;
private Node(E data, Node<E> next) {
this.data = data;
this.next = next;
}
}
Notice that in this version, Node is generic, so I had to add <E> after it every time it appeared. If you go with the static approach, you will have to add <E> after every occurrence of Node in the rest of the class. There are lots of these.
Finally, the message "LinkedList does not take parameters" is self-explanatory. Presumably it says interface LinkedList when it should say interface LinkedList<E>.

Related

Implementation of the 'set' method for a linked List?

I am trying to implement the set method where you pass in the position in a linked list that you want and the value and the set function adds that value into the position specified in the linked list. I have implemented the set function but for some reason The last element disappears in my implementation. I would greatly appreciate any help. Thanks in advance. I would appreciate any expert eyes that will see what I am missing.
/**
* A basic singly linked list implementation.
*/
public class SinglyLinkedList<E> implements Cloneable, Iterable<E>, List<E> {
//---------------- nested Node class ----------------
/**
* Node of a singly linked list, which stores a reference to its
* element and to the subsequent node in the list (or null if this
* is the last node).
*/
private static class Node<E> {
E value;
Node<E> next;
public Node(E e)
{
value = e;
next = null;
}
}
//----------- end of nested Node class -----------
// instance variables of the SinglyLinkedList
private Node<E> head = null; // head node of the list (or null if empty)
private int size = 0; // number of nodes in the list
public SinglyLinkedList() {
} // constructs an initially empty list
// access methods
/**
* Returns the number of elements in the linked list.
*
* #return number of elements in the linked list
*/
public int size() {
return size;
}
/**
* Adds an element to the end of the list.
*
* #param e the new element to add
*/
public void addLast(E e) {
// TODO
}
/**
* Tests whether the linked list is empty.
*
* #return true if the linked list is empty, false otherwise
*/
public boolean isEmpty() {
return size == 0;
}
#Override
public E get(int i) throws IndexOutOfBoundsException {
Node<E> a = head;
if(i<=this.size()) {
int count = 0;
while(count < i) {
count ++;
a = a.next;
}
return a.value;
}
return null;
}
#Override
public E set(int i, E e) throws IndexOutOfBoundsException {
Node<E> current = head;
Node<E> setNode = new Node<E>(e);
if(i==0) {
this.addFirst(e);
}
else if(i==this.size){
this.addLast(e);
}
else {
for(int j=0; current != null && j < (i-1);j++) {
current = current.next;
}
Node<E> temp = current.next;
current.next = setNode;
setNode.next = temp;
}
return setNode.value;
}
// update methods
/**
* Adds an element to the front of the list.
*
* #param e the new element to add
*/
public void addFirst(E e) {
Node<E> first = new Node<>(e);
first.next = this.head;
this.head = first;
this.size++;
}
#SuppressWarnings({"unchecked"})
public boolean equals(Object o) {
// TODO
return false; // if we reach this, everything matched successfully
}
#SuppressWarnings({"unchecked"})
public SinglyLinkedList<E> clone() throws CloneNotSupportedException {
// TODO
return null;
}
/**
* Produces a string representation of the contents of the list.
* This exists for debugging purposes only.
* #return
*/
public String toString() {
for(int i=0;i<this.size();i++) {
System.out.println(this.get(i));
}
return "end of Linked List";
}
public static void main(String[] args) {
SinglyLinkedList <Integer> ll =new SinglyLinkedList <Integer>();
ll.addFirst(5);
ll.addFirst(4);
ll.addFirst(3);
ll.addFirst(2);
ll.set(1,0);
System.out.println(ll);
}
}
Assumptions
addLast method is missing in the code
The error could be there too
Known cause
This code is not incrementing the size inside the set method's for loop.The size is incremented in addLast(possibly) and addFirst and not incremented in other case (final else part)
It is not clear what is planned to do with set method. The way it is implemented now, it behaves more like insert, meaning that it will add new node, bit it does not increase the total count of elements (size).
It the set method is changing the value of the node, which name indicates, then this part is wrong:
else {
for(int j=0; current != null && j < (i-1);j++) {
current = current.next;
}
Node<E> temp = current.next;
current.next = setNode;
setNode.next = temp;
}
It should replace the value instead of adding the new one:
else {
for(int j=0; current != null && j < (i-1);j++) {
current = current.next;
}
current.value=e
}
Also, it looks like the index i is 1-based, while everything else is 0 based. I didn't check the code above, but the concept should be like shown.

How to remove a specific value from linked list in Java?

How to remove a specific value from a linked list java?
I tried to make it in my implementation, but it wasn't easy..
Here is what I'm trying to make:
//How to do this...;<..
int remove(Item item) {
Node cur = first.next;
Node prev = first;
while (cur !=null) {
if (cur.item.equals(item)) {
item = dequeue();
}
cur = cur.next;
// TODO
}
return 0;
}
These are the pre-setup:
public class LinkedQueue<Item> implements Iterable<Item> {
private int N; // number of elements on queue
private Node first; // beginning of queue
private Node last; // end of queue
// helper linked list class
private class Node {
private Item item;
private Node next;
}
/**
* Initializes an empty queue.
*/
public LinkedQueue() {
first = null;
last = null;
N = 0;
assert check();
}
public Item dequeue() {
if (isEmpty()) throw new NoSuchElementException("Queue
underflow");
Item item = first.item;
first = first.next;
N--;
if (isEmpty()) last = null; // to avoid loitering
assert check();
return item;
}
And the main function:
public static void main(String[] args) {
LinkedQueue<String> q = new LinkedQueue<String>();
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
q.enqueue("a");
q.enqueue("b");
q.enqueue("d");
q.enqueue("b");
q.enqueue("abba");
q.enqueue("a");
q.enqueue("z");
q.enqueue("a");
System.out.println(q);
System.out.println("Remove some of elements.");
q.remove("a");
q.remove("f");
q.remove("c");
System.out.println(q);
}
}
And I have a result like this. It doesn't change at all..
a b c a b d b abba a z a
Remove some of elements.
a b d b abba a z a
It only erase value c. I don't know why.
Since Java 8 there is removeIf(Predicate<? super E> filter) method where you can put your own condition.
list.removeIf(cur -> cur.item.equals(item));
As per the details of question,i assume you are fairly new in Java.
What you are asking and the details you are showing are totally different.
LinkedQueue<String> q = new LinkedQueue<String>();
is only applicable if LinkedQueue is a genreic class not a specific impl for Item type class. i.e you are not creating object of LinkedQueue<Item> class. LinkedQueue<String> and LinkedQueue<Item> is different.
cur.equals(item) lack of knowledge of equal contract and difference in == vs equal. i.e you are comparing a two totally different object. One is a Node and other is Item class object.
Suggestion: clear basics, Read book by cathy Sierra.Scjp Sun Certified Programmer for Java 6
As for answer, you are literally not calling remove from main (test it via a print
statement in remove method). That is why you keep getting same answer.
Note: Your really not can't digest real solution even if we tell.
Following code snippet contains various remove() methods, taken from one of my LinkedList implementation, written in Java.
Code
LinkedList.java (partly)
private int size; // node count,
private LinkedListNode<T> head; // first node,
private LinkedListNode<T> end; // last node,
/**
* Remove by index.
*
* #param k index, start from 0,
* #return value of removed node, or null if not removed,
*/
#Override
public T remove(int k) {
checkElementIndex(k);
// find target node, and remember previous node,
LinkedListNode<T> preNode = null;
LinkedListNode<T> node = head;
while (k-- > 0) {
preNode = node;
node = node.next;
}
T result = (T) node.value; // keep return value,
removeNode(node, preNode); // remove
return result;
}
/**
* Remove by value, only remove the first occurrence, if any.
*
* #param v
* #return whether removed,
*/
#Override
public boolean removeValue(T v) {
// find target node, and remember previous node,
LinkedListNode<T> preNode = null;
LinkedListNode<T> node = head;
while (true) {
if (node == null) return false;// not found,
if (node.getValue().compareTo(v) == 0) break; // value found,
preNode = node;
node = node.next;
}
removeNode(node, preNode); // remove
return true;
}
/**
* Remove by value, remove all occurrences.
*
* #param v
* #return count of nodes removed,
*/
#Override
public int removeAllValue(T v) {
int rc = 0;
// find target node, and remember previous node,
LinkedListNode<T> preNode = null;
LinkedListNode<T> node = head;
while (true) {
if (node == null) return rc; // reach end,
if (node.getValue().compareTo(v) == 0) { // value found,
rc++;
if (removeNode(node, preNode)) break; // remove, break if it's end,
continue; // recheck this node, since it become the next node,
}
preNode = node;
node = node.next;
}
return rc;
}
/**
* Remove given node, which guarantee to exists. Also reduce the size by 1.
*
* #param node node to delete,
* #param preNode previous node, could be null,
* #return indicate whether removed node is end,
*/
protected boolean removeNode(LinkedListNode node, LinkedListNode preNode) {
LinkedListNode nextNode = node.next; // next node,
boolean isEnd = (nextNode == null);
if (isEnd) { // target is end,
if (preNode == null) { // target is also head,
head = null;
} else { // target is not head, thus preNode is not null,
preNode.next = null;
}
end = preNode;
} else { // target is not end,
// replace target with next node,
node.next = nextNode.next;
node.value = nextNode.value;
}
size--; // reduce size by 1,
return isEnd;
}
/**
* Remove head node,
*
* #return
*/
#Override
public T removeHead() {
return remove(0);
}
/**
* Remove end node,
*
* #return
*/
#Override
public T removeEnd() {
return remove(size - 1);
}
LinkedListTest.java (partly)
(unit test, via TestNG)
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* LinkedList test.
*
* #author eric
* #date 1/28/19 6:03 PM
*/
public class LinkedListTest {
private int n = 10;
private LinkedList<Integer> llist; // linked list,
private LinkedList<Integer> dupEvenLlist; // linked list, with duplicated even values,
#BeforeMethod
public void init() {
// init llist,
llist = new LinkedList(); // create linked list,
Assert.assertTrue(llist.isEmpty());
LinkedList.appendRangeNum(llist, 0, n); // append range,
// init dupEvenLlist,
dupEvenLlist = new LinkedList(); // create linked list,
LinkedList.appendRangeNum(dupEvenLlist, 0, n); // append range,
LinkedList.appendRangeNum(dupEvenLlist, 0, n, 2); // append range, again, with step as 2 (only even numbers),
Assert.assertEquals(dupEvenLlist.size(), n + n / 2);
}
// non-remove related test cases ... are deleted,
// remove(k) - remove by index,
#Test
public void testRemoveByIndex() {
for (int i = 0; i < n; i++) {
Assert.assertEquals(llist.removeEnd().intValue(), n - 1 - i); // remove by end, in turn it remove by index,
Assert.assertEquals(llist.size(), n - 1 - i);
}
Assert.assertTrue(llist.isEmpty());
}
// remove(v) - remove by value,
#Test
public void testRemoveByValue() {
Assert.assertFalse(llist.removeValue(n)); // not exists,
for (int i = n - 1; i >= 0; i--) {
Assert.assertTrue(llist.removeValue(i)); // remove by value,
Assert.assertEquals(llist.size(), i);
}
Assert.assertTrue(llist.isEmpty());
Assert.assertFalse(llist.removeValue(0)); // empty,
// remove from list with duplicated value,
for (int i = 0; i < n; i++) {
Assert.assertTrue(dupEvenLlist.removeValue(i));
}
Assert.assertFalse(dupEvenLlist.isEmpty());
Assert.assertEquals(dupEvenLlist.size(), n / 2);
}
// removeAll(v) - remove all occurrences by value,
#Test
public void testRemoveAllByValue() {
Assert.assertEquals(dupEvenLlist.removeAllValue(n), 0); // not exists,
int remainSize = dupEvenLlist.size();
for (int i = 0; i < n; i++) {
int rc = dupEvenLlist.removeAllValue(i); // remove all by value,
Assert.assertEquals(rc, i % 2 == 0 ? 2 : 1);
remainSize -= rc;
Assert.assertEquals(dupEvenLlist.size(), remainSize);
}
Assert.assertTrue(dupEvenLlist.isEmpty());
Assert.assertEquals(dupEvenLlist.removeAllValue(0), 0); // empty,
}
}
All test cases would pass.
Explanation
Methods:
T remove(int k), remove by index.
Steps:
* loop to target node,
* for each step,
record:
* previous node,
* this node,
* get next node, of target node,
* get value of target node,
as return value later,
* if target is end,
* if also head,
head = null;
* if not head,
preNode.next = null;
* end = preNode;
* if targe is not end,
replace it with its next node,
logic:
* node.value = nextNode.value;
* node.next = nextNode.next;
* return previously tracked value of target node,
boolean removeValue(T v), remove by value, only remove first occurrence, if any.
The logic is similar as remove by index.
The differences are:
At initial search, compare element instead of loop to index, to find target.
Return boolean that indicate whether removed, instead of removed value,
int removeAllValue(T v), remove all by value, remove all occurrences.
This is similar as remove by value.
Differences:
[inside while()]
It will search all occurrence till end.
After removing an occurrence, it "continue" to recheck the current node.
Because the current node has actual replaced by it's next.
If removed node is end, then return.
This relay on the return value of removeNode().
It record count of removed occurrence.
[return value]
It return count of removed occurrence, instead of boolean.
boolean removeNode(LinkedListNode node, LinkedListNode preNode), remove by node, with preNode given.
Remove given node, which is guaranteed to exists, with previous node given, which might be null.
Return value indicate whether removed node is end, it's mainly used to support removeAllValue().
T removeHead(), T removeEnd(), remove head / end.
Simply calls remove by index, with corresponding index 0 and size - 1 passed.
Tips:
LinkedList represent linkedlist, with fields size, head, end, and generic type T (for value type in node), it's not thread-safe.
checkElementIndex() method, check given index, and throw exception if out of range.
LinkedListNode, represent the node in linked list. with fields value, next.
Complexity
Remove single: O(k)
Remove all by value: O(n)
Where:
k, is the index of target.
n, is size of linkedlist.
In your if statement you are checking if the cur Node is equal to the Item passed in: if (cur.equals(item)).
I think you should be checking if the Item stored in the cur Node is equal to the Item passed into your function: if (cur.item.equals(item)).

Linked List Implementation with Interface

What i need to do in this assignment, is to implement the given methods from the interface. If you could check and give me some feedback on what i've delivered so far, would be very much appreciated.
I am still missing one method unfortunately, public T getNext8thElementOf(int pos). Does anyone has an idea on how to implement it?
/**
* A simple list interface
* #param <T> The type of list element
*/
public interface ISpeedList<T> {
/**
* Returns the current number of elements in the list
*
* #return Current number of elements in the list
*/
public int size();
/**
* Inserts an element at the beginning of the list
*
* #param item Item to be inserted
*/
public void prepend(T item);
/**
* Returns the element at the specified position in the list
*
* #param pos The position of the element in the list starting from 0
*
* #return The specified element in the list
*
* #throws IndexOutOfBoundsException If the requested element is out of
* range
*/
public T getElementAt(int pos);
/**
* Returns the next 8th element of the specified element in the list
*
* #param pos The position of the specified element in the list starting
* from 0
*
* #return The next 8th element of the specified element
*
* #throws IndexOutOfBoundsException If the requested element is out of
* range
*/
public T getNext8thElementOf(int pos);
}
public class SpeedList<T> implements ISpeedList<T> {
/**
* Doubly-linked node class, completely private to the List class,
* as clients don't care about the implementation of the list.
*/
private class Node {
T item;
Node next;
Node previous;
Node(T item, Node next, Node previous) {
this.item = item;
this.next = next;
this.previous = previous;
}
}
/**
* The list itself maintains only a reference to its "header" node.
* The header is a node that does not store any data. Its 'next'
* field points to the first item in the list and its 'previous'
* field points to the last item. This makes all insertions and
* deletions uniform, even at the beginning and the end of the list!
*/
private Node header = new Node(null, null, null);
/**
* The number of items in the list, stored to make size() O(1).
*/
private int size = 0;
/**
* Returns the number of items in the list.
*/
#Override
public int size() {
return size;
}
/**
* Inserts <code>item</code> as the new first item.
*/
#Override
public void prepend(T item) {
addBefore(item, header.next);
}
/**
* Returns the item at the given index position.
*
* #throws IndexOutOfBoundsException
* if index not in [0,size).
*/
#Override
public T getElementAt(int pos) {
return nodeAt(pos).item;
}
#Override
public T getNext8thElementOf(int pos) {
// TODO Auto-generated method stub
return null;
}
//
// PRIVATE HELPER METHODS
//
private Node nodeAt(int pos) {
if (pos < 0 || pos >= size) {
throw new IndexOutOfBoundsException(pos + " for size " + size);
}
Node n = header;
for (int i = 0; i <= pos; i++) {
n = n.next;
}
return n;
}
private void addBefore(T o, Node n) {
Node newNode = new Node(o, n, n.previous);
newNode.previous.next = newNode;
newNode.next.previous = newNode;
size++;
}
}
Is that what you want?
#Override
public T getNext8thElementOf(int pos) {
int eight = 8;
Node nodo = this.nodeAt(pos);
while(eight > 0) {
eight--;
nodo = nodo.next;
}
return nodo.item;
}

Implementing an Iterator to a Doubly Linked List

I have been having trouble trying to figure out how to add an iterator to this, I am really confused how to start here is the code. I imported the Iterator but I have no idea where I would begin to add it in here
public class DoublyLinkedList<E> implements Iterator <E> {
/**
* Node of a doubly linked list, which stores a reference to its
* element and to both the previous and next node in the list.
*/
private static class Node<E> {
/** The element stored at this node */
private E element; // reference to the element stored at this node
/** A reference to the preceding node in the list */
private Node<E> prev; // reference to the previous node in the list
/** A reference to the subsequent node in the list */
private Node<E> next; // reference to the subsequent node in the list
/**
* Creates a node with the given element and next node.
*
* #param e the element to be stored
* #param p reference to a node that should precede the new node
* #param n reference to a node that should follow the new node
*/
public Node(E e, Node<E> p, Node<E> n) {
element = e;
prev = p;
next = n;
}
// public accessor methods
/**
* Returns the element stored at the node.
* #return the element stored at the node
*/
public E getElement() {
return element;
}
/**
* Returns the node that precedes this one (or null if no such node).
* #return the preceding node
*/
public Node<E> getPrev() {
return prev;
}
/**
* Returns the node that follows this one (or null if no such node).
* #return the following node
*/
public Node<E> getNext() {
return next;
}
// Update methods
/**
* Sets the node's previous reference to point to Node n.
* #param p the node that should precede this one
*/
public void setPrev(Node<E> p) {
prev = p;
}
/**
* Sets the node's next reference to point to Node n.
* #param n the node that should follow this one
*/
public void setNext(Node<E> n) {
next = n;
}
}
// instance variables of the DoublyLinkedList
/** Sentinel node at the beginning of the list */
private Node<E> header; // header sentinel
/** Sentinel node at the end of the list */
private Node<E> trailer; // trailer sentinel
/** Number of elements in the list (not including sentinels) */
private int size = 0; // number of elements in the list
/** Constructs a new empty list. */
public DoublyLinkedList() {
header = new Node<>(null, null, null); // create header
trailer = new Node<>(null, header, null); // trailer is preceded by header
header.setNext(trailer); // header is followed by trailer
}
// public accessor methods
/**
* Returns the number of elements in the linked list.
* #return number of elements in the linked list
*/
public int size() {
return size;
}
/**
* Tests whether the linked list is empty.
* #return true if the linked list is empty, false otherwise
*/
public boolean isEmpty() {
return size == 0;
}
/**
* Returns (but does not remove) the first element of the list.
* #return element at the front of the list (or null if empty)
*/
public E first() {
if (isEmpty()) return null;
return header.getNext().getElement(); // first element is beyond header
}
/**
* Returns (but does not remove) the last element of the list.
* #return element at the end of the list (or null if empty)
*/
public E last() {
if (isEmpty()) return null;
return trailer.getPrev().getElement(); // last element is before trailer
}
// public update methods
/**
* Adds an element to the front of the list.
* #param e the new element to add
*/
public void addFirst(E e) {
addBetween(e, header, header.getNext()); // place just after the header
}
/**
* Adds an element to the end of the list.
* #param e the new element to add
*/
public void addLast(E e) {
addBetween(e, trailer.getPrev(), trailer); // place just before the trailer
}
/**
* Removes and returns the first element of the list.
* #return the removed element (or null if empty)
*/
public E removeFirst() {
if (isEmpty()) return null; // nothing to remove
return remove(header.getNext()); // first element is beyond header
}
/**
* Removes and returns the last element of the list.
* #return the removed element (or null if empty)
*/
public E removeLast() {
if (isEmpty()) return null; // nothing to remove
return remove(trailer.getPrev()); // last element is before trailer
}
// private update methods
/**
* Adds an element to the linked list in between the given nodes.
* The given predecessor and successor should be neighboring each
* other prior to the call.
*
* #param predecessor node just before the location where the new element is inserted
* #param successor node just after the location where the new element is inserted
*/
private void addBetween(E e, Node<E> predecessor, Node<E> successor) {
// create and link a new node
Node<E> newest = new Node<>(e, predecessor, successor);
predecessor.setNext(newest);
successor.setPrev(newest);
size++;
}
/**
* Removes the given node from the list and returns its element.
* #param node the node to be removed (must not be a sentinel)
*/
private E remove(Node<E> node) {
Node<E> predecessor = node.getPrev();
Node<E> successor = node.getNext();
predecessor.setNext(successor);
successor.setPrev(predecessor);
size--;
return node.getElement();
}
/**
* Produces a string representation of the contents of the list.
* This exists for debugging purposes only.
*/
public String toString() {
StringBuilder sb = new StringBuilder("(");
Node<E> walk = header.getNext();
while (walk != trailer) {
sb.append(walk.getElement());
walk = walk.getNext();
if (walk != trailer)
sb.append(", ");
}
sb.append(")");
return sb.toString();
}
#Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
#Override
public E next() {
// TODO Auto-generated method stub
return null;
}
} //----------- end of DoublyLinkedList class -----------
First, your List should not implement the Iterator interface. Iterator is capable to traverse only once. Usually lists implement Iterable interface and have iterator() method which can create a new iterator for this list. There are several similar questions answered already. Check this for example.
You do not now how to implement next() and hasNext() methods?
You can store a "current" node element in a field (initialized by first()), and in hasNext() method compare it with last(). In next() method you should assign current node the getNext() of it an return the node.

Java Iterator for circular linked list

I've created a CircularLinkedList class, instead of using the util LinkedList class. The problem is based off of the Josephus problem, stating that for a circle of 20 people, each 12th person is to be killed until it is determined which position the survivor will be left standing in (using an Iterator). I'm confused as to how I could use an Iterator with this problem, since I'm using my own class instead of LinkedList, which already has an iterator() method so that I could declare an Iterator like this:
Iterator<E> iter = cll.iterator();
I have no idea how I would write my own Iterator method, and I feel like I have to be over thinking this. Any help is appreciated! I can post my code if it would clear anything up that I forgot to mention
I'm still stuck on this, so I figured I'd post my code to see if anyone can help. It's a lot, so I apologize.
Itr class (Iterator)
import java.util.Iterator;
public class Itr<E> extends CircularLinkedList<E> implements Iterator<E>
{
/** the size of the list */
private int size = 0;
/** for the hasNext() method for Iterator */
private int nextNode = 0;
/** two Nodes used for next() method for Iterator */
private Node<E> lastReturned = null;
private Node<E> nextUp;
/** part of the Iterator implementation */
public boolean hasNext()
{
return nextNode < size;
}
/** part of the Iterator implementation */
public E next()
{
lastReturned = nextUp;
nextUp = nextUp.getNext();
nextNode++;
return lastReturned.data;
}
/** part of the Iterator implementation */
public void remove()
{
Node<E> lastNext = lastReturned.getNext();
if (lastReturned == null)
nextUp = lastNext;
else
nextNode--;
lastReturned = null;
}
}
Josephus class
public class Josephus<E>
{
public static void main(String[] args)
{
CircularLinkedList cll = new CircularLinkedList();
Itr iter = cll.iterator();
int lastMan = 0;
int n = 20;
int passes = 12;
while(n > 1)
{
iter.next();
for(int i = 0; i < n; i += passes)
{
iter.hasNext();
iter.remove();
if(n == 1)
lastMan = n;
}
}
System.out.println("Survior: " + lastMan);
}
}
CircularLinkedList class
public class CircularLinkedList<E>
{
public class Node<E>
{
/* data value **/
public E data;
/* the link **/
private Node<E> next = null;
/** constructs a Node with given data and link
* #param data the data value
* #param next the link
*/
public Node(E data, Node<E> next)
{
this.data = data;
this.next = next;
}
/** construct a Node with given data value
* #param data the data value
*/
public Node(E data)
{
this.data = data;
}
/** return the data value of a Node
* #return the data value
*/
public E getData()
{
return data;
}
/** set the next Node in a list
* #param append the data value that the new Node will contain
*/
public void setNext(Node append)
{
next = append;
}
/** return the next Node
* # return the next Node
*/
public Node<E> getNext()
{
if(current.next == null)
current.next = current;
return next;
}
}
/** a reference into the list */
private Node<E> current = null;
/** the size of the list */
private int size = 0;
/** helper methods */
/** remove the first occurance of element item.
* #param item the item to be removed
* #return true if item is found and removed; otherwise, return false.
*/
public void removeItem(E item)
{
Node<E> position = current;
Node<E> nextPosition1,
nextPosition2;
while (position.next != null)
{
if(position.getNext().getData().equals(item))
{
nextPosition1 = position.getNext();
nextPosition2 = nextPosition1.getNext();
position.setNext(nextPosition2);
}
else
{
position = position.getNext();
}
}
}
/** set the first Node in a list
* #param append the data value that the new Node will contain
*/
public void addFirst(E append)
{
current = new Node<E>(append, current);
size++;
}
/** add a new Node as the last in the List
* #param data value of the new Node
*/
public void addNext(E value)
{
// location for new value
Node<E> temp = new Node<E>(value,null);
if (current != null)
{
// pointer to possible tail
Node<E> finger = current;
while (finger.next != null)
{
finger = finger.next;
}
finger.setNext(temp);
} else current = temp;
size++;
}
/** return the data value of the fourth Node in the list
* #return the data value
*/
public E printFourth()
{
current.next.next.next = current;
return current.next.next.next.getData();
}
/** return the size of the LinkedList
* #return the size
*/
public int size()
{
return size;
}
public E get(int index)
{
Node<E> temp = null;
for(int i = 0; i < index; i++)
{
temp = current.next;
System.out.print(temp.getData() + " ");
}
return temp.getData();
}
public Itr<E> iterator()
{
return new Itr<E>();
}
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("[");
Node<E> aux = this.current;
boolean isFirst = true;
while(aux != null)
{
if(!isFirst)
{
sb.append(", ");
}
isFirst = false;
sb.append(aux.data.toString());
aux=aux.next;
}
return sb.append("]").toString();
}
}
I'm getting a NullPointerException from the next() method in the Itr class on the line
nextUp = nextUp.getNext();
Am I doing something wrong in the CircularLinkedList class for it to not actually be circular or is there a problem with my driver/Itr classes? I'm kind of lost at this point. Any help is appreciated.
Create a custom class which implements Iterator and return the custom Iterator from your CLL.iterator method.
See LinkedList#ListItr for inspiration - but only conside the Iterator methods (next, hasNext, remove) for this exercise. A true circular linked-list will simply follow the next node, always, and has no end - hasNext will always return true if there is at least one element. If your CLL implementation has an "end", then make sure to "move back to the start" when it is encountered.
In addition, the CLL class should conform to Iterable, which means it has an iterator method to obtain an Iterator.

Categories