Reputation: 3148
I'm writing a simple implementation of a Bag in Java. I am implementing Iterable
and writing my own LinkedList
Iterator. So I'm racking my brain; I am trying to add elements to the linked list. I have a working implementation (the commented out code in the add()
function). However, I do not understand why the following code does not work:
current.item = item;
Node<T> nextNode = new Node<T>();
current.next = nextNode;
current = nextNode;
So, given that the list is empty and the current head is initialized but has no item or next: I assign item to the current item, create a new node, set it to the current's next and change the current (head) to the node I just created. Adding two items to the list, I printed out the objects for posterity:
current: Bag$Node@4524411f next: Bag$Node@401e7803
current: Bag$Node@401e7803 next: Bag$Node@10dba097
current: Bag$Node@10dba097 next: Bag$Node@1786f9d5
current: Bag$Node@1786f9d5 next: Bag$Node@704d6e83
It looks clearly, to me at least, that the next is getting set with a new node each time just fine. I get all four elements added to the bag, but the item is lost and returns null for each index. The toArray() function shows [null, null, null, null]
I'm sure it's something blindingly simple. Below is the entire implementation.
import java.util.Iterator;
public class Bag<T> implements Iterable<T> {
private Node current;
//Node<T> head;
private int numberofProducts;
T[] myBag;
int defaultCapacity;
public Iterator<T> iterator() {
return new ListIterator<T>(current);
}
public Bag(int defaultCapacity) {
this.current = new Node<T>();
this.numberofProducts = 0;
this.defaultCapacity = defaultCapacity;
}
public void add(T item) {
if(isFull()) {
System.out.println("bags full, yo");
return;
}
current.item = item;
Node<T> nextNode = new Node<T>();
current.next = nextNode;
current = nextNode;
numberofProducts++;
//Node<T> nextNode = current;
//current = new Node<T>();
//current.item = item;
//current.next = nextNode;
//numberofProducts++;
}
public Object[] toArray() {
Object[] array = new Object[size()];
int i = 0;
Node<T> node = current;
//Node<T> node = head;
while(node.next != null) {
array[i] = node.item;
node = node.next;
i++;
}
return array;
}
public boolean isEmpty() {
return this.numberofProducts <= 0;
}
public boolean isFull() {
return this.numberofProducts >= defaultCapacity;
}
public int size() {
return this.numberofProducts;
}
private class Node<T> {
private T item;
private Node<T> next;
}
private class ListIterator<T> implements Iterator<T> {
private Node<T> current;
public ListIterator(Node<T> first) {
current = first;
}
public boolean hasNext() {
return current != null;
}
public T next() {
if(hasNext()) {
T item = current.item;
current = current.next;
return item;
}
return null;
}
public void remove() {
}
}
}
Upvotes: 0
Views: 7591
Reputation: 11
The problem is with your logic written in the add()
method. Whenever adding the new data to Bag, your root node is changing and pointing to the last node of your Bag. Since the next to last node is null, that's why the iterator is not returning anything. Refer to this link for the exact solution.
Upvotes: 1
Reputation: 1842
From what I can see, the reason it's not acting as a Linked List is because you are not retaining a reference to the first element added. Rather you retain a reference to the last (current
) element added.
You can resolve this by adding a class field reference the first element added
T head
Then in your add()
method, set head
to the Node
you create. Then when you construct your ListIterator, pass head
as the parameter.
You can change add(T item)
to showing like this:
public void add(T item) {
if (!isFull()) {
Node<T> toAdd = new Node<>();
toAdd.item = item;
current.next = toAdd;
current = toAdd;
if (head == null) {
head = toAdd;
}
}
}
Then add the class field Node<T> head
to your Bag<T>
class.
Additionally, I'm not sure why Node
is a static class, plus a number of other changes I won't get into now, but I guess the class is incomplete at present.
Upvotes: 1
Reputation:
The item values aren't lost. The problem is that you lose track of the head of the linked list. Your current
variable keeps track of the tail already, and since your toArray()
method starts at current
, the while
loop never executes because there are no elements after the tail element of the list.
Consequently, you just end up with an array of default-initialized Object
values, i.e. null
.
To fix this, you need another instance variable to keep track of the head of the list, and this is what you'll use in your toArray()
method.
Upvotes: 1