I'm using a custom Iterator to a custom LinkedList structure in my project. However when iterating through the LinkedList, the Iterator does not remove the entry from the given list.
My custom Iterator:
package plotter.structures;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
*
* #author croemheld
*
* #param <T> The type of the elements of the {#link LinkedList}.
*/
public class LinkedListIterator<T> implements Iterator<T> {
/**
* Previous element in the {#link LinkedListIterator}.
*/
private ListNode<T> previous = null;
/**
* Current element in the {#link LinkedListIterator}.
*/
private ListNode<T> current;
private LinkedList<T> collection;
/**
* Returns an instance of {#link LinkedListIterator} which iterates from the head
* to the tail of a {#link LinkedList}.
*
* #param collection The collection to iterate through.
*/
public LinkedListIterator(LinkedList<T> collection) {
this.collection = collection;
this.current = collection.getHead();
}
/**
* Returns a {#link LinkedListIterator} which starts at a specific index.
*
* #param collection The {#link LinkedList} for this {#link LinkedListIterator}.
* #param index The index to start at.
*/
public LinkedListIterator(LinkedList<T> collection, int index) {
this.current = collection.get(index);
}
#Override
public boolean hasNext() {
return this.current != null;
}
#Override
public T next() {
if(!hasNext()) {
throw new NoSuchElementException();
}
T element = this.current.getElement();
this.previous = this.current;
this.current = this.current.getNext();
return element;
}
#Override
public void remove() {
if(this.previous.getPrev() != null) {
this.previous.getPrev().setNext(this.previous.getNext());
}
this.current.setPrev(this.previous.getPrev());
}
/**
*
* #return The next element of this {#link LinkedListIterator}.
*/
public T peek() {
if(!hasNext()) {
return null;
}
return this.current.getElement();
}
/**
* Determines if the next element is null or equal to the current element.
*
* #param element The element of the current iteration.
*
* #return True, if the next element is equal to the current one or if the next element is null.
*/
public boolean hasEqualFollower(T element) {
return (peek() != null && !peek().equals(element) || peek() == null);
}
}
My LinkedList reduced to the method that does not work properly:
public class LinkedList<T> implements Collection<T> {
/**
* The head {#link ListNode} of this {#link LinkedList}.
*/
private ListNode<T> head;
/**
* The tail {#link ListNode} of this {#link LinkedList}.
*/
private ListNode<T> tail;
/**
* The length of this {#link LinkedList}.
*/
private int size;
// [...]
#Override
public boolean removeIf(Predicate<? super T> predicate) {
int count = size();
LinkedListIterator<T> iterator = new LinkedListIterator<T>(this);
while(iterator.hasNext()) {
T element = iterator.next();
if(predicate.test(element)) {
iterator.remove();
}
}
return size() < count;
}
// [..]
}
The predicate.test(element) properly returns true for the said element, but it does not remove the element from my LinkedList.
The invocation looks like this:
result.removeIf(node -> node.getValue().equals(ComplexNumber.ZERO.toString()));
At this point the equals method compares two String objects with both having the value (0.0 + 0.0i) (complex number representation) and returns true correctly.
Why is the element still in the list after the removeIf invocation?
Related
I am trying to implement addFirst to a singly linked list in Java. For some reason my implementation does not print out the linked list correctly. I prdict the problem is in either the addFirst, get, or toString methods. Any help would be greatly appreciated. Thanks in advance.
I predict that i am not creating the nodes correctly and I would appreciate an extra eye to spot what I am missing
import java.util.Iterator;
/**
* 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)
{
e = value;
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;
}
/**
* 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 {
if(i>this.size()) {
int count = 0;
Node<E> a = head;
while(count != i) {
count ++;
System.out.println(a.value);
a = a.next;
}
}
return null;
}
#Override
public E set(int i, E e) throws IndexOutOfBoundsException {
return null;
}
#Override
public void add(int i, E e) throws IndexOutOfBoundsException {
}
#Override
public E remove(int i) throws IndexOutOfBoundsException {
return null;
}
/**
* 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() {
// TODO
return null;
}
/**
* Returns the last node of the list
*
* #return last node of the list (or null if empty)
*/
public Node<E> getLast() {
// TODO
return null;
}
/**
* 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() {
// TODO
return null;
}
// update methods
/**
* Adds an element to the front of the list.
*
* #param e the new element to add
*/
public void addFirst(E e) {
if(this.size() == 0) {
Node<E> first = new Node<E>(e);
this.size++;
this.head = first;
} else {
Node<E> first = new Node<E>(e);
first.next = this.head;
this.head = first;
this.size++;
}
}
/**
* Adds an element to the end of the list.
*
* #param e the new element to add
*/
public void addLast(E e) {
// TODO
}
/**
* Removes and returns the first element of the list.
*
* #return the removed element (or null if empty)
*/
public E removeFirst() {
// TODO
return null;
}
#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";
}
private class SinglyLinkedListIterator<E> implements Iterator<E> {
#Override
public boolean hasNext() {
// TODO
return false;
}
#Override
public E next() {
// TODO
return null;
}
}
public Iterator<E> iterator() {
return new SinglyLinkedListIterator<E>();
}
public static void main(String[] args) {
//ArrayList<String> all;
//LinkedList<String> ll;
/*SinglyLinkedList<String> sll = new SinglyLinkedList<String>();
String[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
for (String s : alphabet) {
sll.addFirst(s);
sll.addLast(s);
}
System.out.println(sll.toString());
for (String s : sll) {
System.out.print(s + ", ");
}
*/
SinglyLinkedList <Integer> ll =new SinglyLinkedList <Integer>();
ll.addFirst(1);
ll.addFirst(3);
System.out.println(ll);
}
}
You have a bug in the constructor of the Node class:
public Node(E e)
{
e = value;
should be
public Node(E e)
{
value = e;
Also, assuming this is the method that you've added:
* Adds an element to the front of the list.
*
* #param e the new element to add
*/
public void addFirst(E e) {
if(this.size() == 0) {
Node<E> first = new Node<E>(e);
this.size++;
this.head = first;
} else {
Node<E> first = new Node<E>(e);
first.next = this.head;
this.head = first;
this.size++;
}
}
You don't really have to differentiate between the cases when the list is empty or otherwise.
You could:
Create a new node
Chain the current head to this newly created node
Set the head to the newly created node
Handle updates to other auxiliary variables, e.g. size in this case
* 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++;
}
I have a QueueRunner class made. I am trying to figure out out to iterate to the head of my queue after poll() or offer() to return the head of my queue using peek(). I am having trouble returning the head or front of the queue though.
Public class Queue<T> {
private ArrayList<T> elements;
public Queue() {
this.elements = new ArrayList<T>();
}
/**
* Offers an element to the end of the queue.
*
* #param T item
*/
public void offer(T element) {
this.elements.add(element);
}
/**
* Peeks at, but does not remove, the element at the head of the queue.
*
* #return T
*/
public T peek() {
if(this.elements.size()==0) {
return null;
}
else {
return this.elements;
// return this.elements.get(this.elements.size()-1);
}
}
/**
* Polls an element from the head of the queue.
*
* #return T
*/
public T poll() {
return this.elements.remove(0);
}
this.elements.get(0) would return you the head/front of the queue. Since a queue is FIFO, the first element that was added will be the first to go and thus the head of the queue.
It looks like you are returning the ArrayList<T> itself not an element and returning the last element is commented out.
else {
return this.elements;
// return this.elements.get(this.elements.size()-1);
}
So I have looked over this code for the past couple hours and cannot find the bug. Subset takes in an array for 3 String characters and it will read through and print them out fine, but if I add more than three elements it kicks out an arrayoutofbounds exception and I cannot figure out why. I can manually add them in one by one and it will work but thats not the way that the program was designed to work. Im sure the solution is simple but I cannot find it. Any ideas? Thanks so much.
package a02;
import java.util.Iterator;
import edu.princeton.cs.algs4.StdRandom;
/**
*
* #author Danny
*
* #param <Item>
*/
public class RandomizedQueue<Item> implements Iterable<Item> {
private Item[] queue ;
private int size;
/**
* Constructs an empty randomized queue.
*/
public RandomizedQueue() {
queue = (Item[])new Object[1];
size=0;
}
/**
* parameterized constructor for the Iterator class.
* #param array
*/
private RandomizedQueue(Item[] array)
{
int count = 0;
queue = array;
while(queue[count]!=null)
count++;
queue = (Item[])new Object[array.length];
for(int i=0;i<count;i++)
queue[i]=array[i];
size=count;
}
private Item[] getArray() {
return queue;
}
/**
* Checks to see if the queue is empty.
* #return
*/
public boolean isEmpty() {
return size<=0;
}
/**
* Returns the number of items in the queue.
* #return
*/
public int size() {
return size;
}
/**
* Adds an item.
* #param item
*/
public void enqueue(Item item) {
if (item == null)
throw new java.lang.NullPointerException();
if (size == queue.length)
resize(2*queue.length);
queue[size]= item;
size++;
}
/**
* Deletes and returns a random item
* #return
*/
public Item dequeue() {
if (isEmpty())
throw new java.util.NoSuchElementException();
int index = StdRandom.uniform(size);
Item item = queue[index];
if(index == size-1)
queue[index] = null;
else {
queue[index] = queue[size-1];
queue[size-1]=null;
}
size--;
if(size<=queue.length/4)
resize(queue.length/2);
return item;
}
/**
* Returns a random item, but does not delete it.
* #return
*/
public Item sample() {
if (isEmpty())
throw new java.util.NoSuchElementException();
int index = StdRandom.uniform(size);
return queue[index];
}
/**
* Returns an independent iterator over items in random order.
*/
public Iterator<Item> iterator(){
return new RandomizedQueueIterator();
}
/**
*
* #author Danny
*
*/
private class RandomizedQueueIterator implements Iterator<Item>{
RandomizedQueue<Item> rq = new RandomizedQueue<>(queue);
#Override
public boolean hasNext() {
return rq.size()!=0;
}
#Override
public Item next() {
return rq.dequeue();
}
#Override
public void remove() {
throw new java.lang.UnsupportedOperationException();
}
}
/**
* Resizes the queue array by the given size.
* #param d
*/
private void resize(int d) {
Item[] newArray = (Item[]) new Object[d];
for(int i = 0;i<size;i++)
newArray[i]=queue[i];
queue = newArray;
}
/**
* Unit Testing
* #param args
*/
public static void main(String[] args) {
RandomizedQueue<Integer> rq = new RandomizedQueue<>();
rq.enqueue(1);
rq.enqueue(2);
rq.enqueue(3);
rq.enqueue(4);
rq.enqueue(5);
rq.enqueue(6);
rq.enqueue(7);
Iterator<Integer> iterator1 = rq.iterator();
while(iterator1.hasNext())
System.out.println(iterator1.next());
System.out.println();
Iterator<Integer> iterator2 = rq.iterator();
while(iterator2.hasNext())
System.out.println(iterator2.next());
}
}
package a02;
import java.util.Iterator;
public class Subset {
public static void main(String[] args) {
//char [] c = {'b', 'a', 'C'};
String[] c= {"hello", "hi", "howdy", "english"};
RandomizedQueue<String> queue = new RandomizedQueue<String>();
for (int i=0;i<c.length; i++)
queue.enqueue(c[i]);
int k=3;
Iterator<String> iterator=queue.iterator();
for (int i=0; i<k;i++) {
System.out.println(iterator.next());
}
}
}
In the constructor RandomizedQueue(Item[] array) you need to add a bounds check before accessing queue.
Change:
while(queue[count]!=null)
to
while(count < queue.length && queue[count]!=null)
Java newbie question: I'm trying to implement a deque in Java and am having issues with the dequeueBack (remove an element from the rear of the queue) and enqueueFront (add an element to the front of the queue) methods. I've gotten the opposite methods to work (dequeueFront and enqueueBack), but I'm stumped at this point. Any suggestions?
public class Carr_A06Q4
{
/**
* Program entry point for deque testing.
* #param args Argument list.
*/
public static void main(String[] args)
{
LinkedDequeue<Integer> deque = new LinkedDequeue<Integer>();
System.out.println("DEQUE TESTING");
//per Q1
deque.enqueueBack(3);
deque.enqueueBack(7);
deque.enqueueBack(4);
deque.dequeueFront();
deque.enqueueBack(9);
deque.enqueueBack(8);
deque.dequeueFront();
System.out.println("The size of the deque is: " + deque.size());
System.out.println("The deque contains:\n" + deque.toString());
//new features
System.out.println(deque.dequeueFront());
deque.enqueueFront(1);
deque.enqueueFront(11);
deque.enqueueFront(3);
deque.enqueueFront(5);
System.out.println(deque.dequeueBack());
System.out.println(deque.dequeueBack());
System.out.println(deque.last());
deque.dequeueFront();
deque.dequeueFront();
System.out.println(deque.first());
System.out.println("The size of the deque is: " + deque.size());
System.out.println("The deque contains:\n" + deque.toString());
}
/**
* LinkedDeque represents a linked implementation of a deque.
*
*/
public static class LinkedDequeue<T> implements DequeADT<T>
{
private int count;
private LinearDoubleNode<T> head, tail; //front, back
/**
* Creates an empty queue.
*/
public LinkedDequeue()
{
count = 0;
head = tail = null;
}
/**
* Adds the specified element to the tail of this queue.
* #param element the element to be added to the tail of the queue
*/
public void enqueueBack(T element)
{
LinearDoubleNode<T> node = new LinearDoubleNode<T>(element);
if (isEmpty())
head = node;
else
tail.setNext(node);
tail = node;
count++;
}
/**
* Adds the specified element to the head of this queue.
* #param element the element to be added to the head of the queue
*/
public void enqueueFront(T element)
{
LinearDoubleNode<T> node = new LinearDoubleNode<T>(element);
count++ ;
if (head == null)
{
head = node;
}
else
{
node.setNext(head);
head = node;
}
}
/**
* Removes the element at the head of this queue and returns a
* reference to it.
* #return the element at the head of this queue
* #throws EmptyCollectionException if the queue is empty
*/
public T dequeueFront() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("queue");
T result = head.getElement();
head = head.getNext();
count--;
if (isEmpty())
head = null;
return result;
}
/**
* Removes the element at the tail of this queue and returns a
* reference to it.
* #return the element at the tail of this queue
* #throws EmptyCollectionException if the queue is empty
*/
public T dequeueBack() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("queue");
T result = tail.getElement();
tail = tail.getNext();
if (isEmpty())
head = null;
count --;
return result;
}
/**
* Returns a reference to the element at the head of this queue.
* The element is not removed from the queue.
* #return a reference to the first element in this queue
* #throws EmptyCollectionsException if the queue is empty
*/
public T first() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
T result = head.getElement();
return result;
}
/**
* Returns a reference to the element at the tail of this queue.
* The element is not removed from the queue.
* #return a reference to the first element in this queue
* #throws EmptyCollectionsException if the queue is empty
*/
public T last() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
T result = tail.getElement();
return result;
}
/**
* Returns true if this queue is empty and false otherwise.
* #return true if this queue is empty
*/
public boolean isEmpty()
{
if (head == null)
{
return true;
}
else
{
return false;
}
}
/**
* Returns the number of elements currently in this queue.
* #return the number of elements in the queue
*/
public int size()
{
return count;
}
/**
* Returns a string representation of this queue. The front element
* occurs first, and each element is separated by a space. If the
* queue is empty, returns "empty".
* #return the string representation of the queue
*/
public String toString()
{
StringBuilder sb = new StringBuilder();
LinearDoubleNode<T> tmp = head;
while (tmp != null)
{
sb.append(tmp.getElement()).append(" ");
tmp = tmp.getNext();
}
return sb.toString();
}
}
}
I need to get an output of:
DEQUE TESTING:
The size of the deque is: 3
The deque contains:
498
4
8
9
1
11
The size of the deque is: 2
The deque contains:
11 1
But instead I'm getting:
DEQUE TESTING:
The size of the deque is: 3
The deque contains:
498
4
8
and then I get a NullPointerException in the dequeueBack method.
Any help is appreciated!
Also, the interface is:
public interface DequeADT<T>
{
/**
* Adds one element to the front of this deque.
* #param element the element to be added to the front of the deque
*/
public void enqueueFront(T element); //deque specific
/**
* Adds one element to the back of this deque.
* #param element the element to be added to the back of the deque
*/
public void enqueueBack(T element);
/**
* Removes and returns the element at the front of this deque.
* Should throw an exception if the deque is empty.
* #return the element at the front of this deque
*/
public T dequeueFront();
/**
* Removes and returns the element at the back of this deque.
* Should throw an exception if the deque is empty.
* #return the element at the back of the deque.
*/
public T dequeueBack(); //deque specific
/**
* Returns, without removing, the element at the front of this deque.
* Should throw an exception if the deque is empty.
* #return the first element in the deque
*/
public T first();
/**
* Returns, without removing, the element at the back of this deque.
* Should throw an exception if the deque is empty.
* #return the last element in the deque
*/
public T last(); //deque specific
/**
* Returns true if this deque is empty and false otherwise.
* #return true if this deque is empty
*/
public boolean isEmpty();
/**
* Returns the number of elements in this deque.
* #return the number of elements in the deque
*/
public int size();
/**
* Returns a string representation of this deque. The front element
* occurs first, and each element is separated by a space. If the
* deque is empty, returns "empty".
* #return the string representation of the deque
*/
public String toString();
}
and a description of the node is:
public class LinearDoubleNode<T>
{
private LinearDoubleNode<T> next;
private T element;
/**
* Creates an empty node.
*/
public LinearDoubleNode()
{
next = null;
element = null;
}
/**
* Creates a node storing the specified element.
* #param elem element to be stored
*/
public LinearDoubleNode(T elem)
{
next = null;
element = elem;
}
/**
* Returns the node that follows this one.
* #return reference to next node
*/
public LinearDoubleNode<T> getNext()
{
return next;
}
/**
* Sets the node that follows this one.
* #param node node to follow this one
*/
public void setNext(LinearDoubleNode<T> node)
{
next = node;
}
/**
* Returns the element stored in this node.
* #return element stored at the node
*/
public T getElement()
{
return element;
}
/**
* Sets the element stored in this node.
* #param elem element to be stored at this node
*/
public void setElement(T elem)
{
element = elem;
}
}
The only way you can get that to perform, is for the internal list to be double-linked.
Otherwise you'll have to scan the entire list to find the second-last node, in order to remove the last node.
Double-ended queue ➔ Double-linked list
or dynamic array (see Implementations section).
public class LinkedDQueue implements DQueue {
private int size;
private LinearDoubleNode<T> head, tail; // front, back
private int capcity;
public LinkedDQueue() {
capcity = 10;
}
public LinkedDQueue(int capcity) {
this.capcity = capcity;
}
#Override
public boolean full() {
return size == capcity;
}
#Override
public void addFirst(T e) throws CapcityExceededException {
if (full())
throw new CapcityExceededException("size overflow");
LinearDoubleNode<T> node = new LinearDoubleNode<T>(e);
if (head == null) {
head = node;
tail = node;
} else {
node.setNext(head);
head = node;
}
size++;
}
#Override
public void addLast(T e) throws CapcityExceededException {
LinearDoubleNode<T> node = new LinearDoubleNode<T>(e);
if (full())
throw new CapcityExceededException("size overflow");
if (tail == null) {
head = tail = node;
} else {
tail.setNext(node);
node.setPrevious(tail);
}
tail = node;
size++;
}
#Override
public T removeFirst() {
if (isEmpty())
return null;
T result = head.getElement();
head.getNext().setPrevious(null);
head = head.getNext();
size--;
return result;
}
#Override
public T removeLast() {
LinearDoubleNode<T> temp = tail; // Save address of Node to delete
if (isEmpty()) {
return null;
}
if (head == tail) {
head = null;
tail = null;
size = 0;
return tail.getElement();
}
T result = tail.getElement();
tail = temp.getPrevious();
tail.setNext(null);
size--;
return result;
}
#Override
public T getFirst() {
if (isEmpty())
return null;
T result = head.getElement();
return result;
}
#Override
public T getLast() {
if (isEmpty())
return null;
T result = tail.getElement();
return result;
}
#Override
public int length() {
return size;
}
#Override
public void reverse() {
}
#Override
public boolean isEmpty() {
if (head == null) {
return true;
} else {
return false;
}
}
#Override
public int size() {
return size;
}
#Override
public String toString() {
LinearDoubleNode<T> temp = head; // Save address of Node to delete
StringBuilder builder = new StringBuilder();
while (temp != null) {
builder.append(temp.getElement() + "");
temp = temp.getNext();
}
return builder.toString();
}
class LinearDoubleNode<T> {
private LinearDoubleNode<T> next;
private LinearDoubleNode<T> previous;
private T element;
/**
* Creates an empty node.
*/
public LinearDoubleNode() {
next = null;
previous = null;
element = null;
}
/**
* Creates a node storing the specified element.
*
* #param elem
* element to be stored
*/
public LinearDoubleNode(T elem) {
next = null;
previous = null;
element = elem;
}
/**
* Returns the node that follows this one.
*
* #return reference to next node
*/
public LinearDoubleNode<T> getNext() {
return next;
}
public LinearDoubleNode<T> getPrevious() {
return previous;
}
public void setPrevious(LinearDoubleNode<T> previous) {
this.previous = previous;
}
/**
* Sets the node that follows this one.
*
* #param node
* node to follow this one
*/
public void setNext(LinearDoubleNode<T> node) {
next = node;
}
/**
* Returns the element stored in this node.
*
* #return element stored at the node
*/
public T getElement() {
return element;
}
/**
* Sets the element stored in this node.
*
* #param elem
* element to be stored at this node
*/
public void setElement(T elem) {
element = elem;
}
}
}
class CapcityExceededException extends Exception {
private String message;
public CapcityExceededException(String message) {
super(message);
this.message = message;
}
}
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The type Deque.
*
* #param <Item> the type parameter
*/
public class Deque<Item> implements Iterable<Item> {
/**
* The Head.
*/
private Node<Item> head;
/**
* The Tail.
*/
private Node<Item> tail;
/**
* The Deque size.
*/
private int dequeSize;
private class Node<Item> {
/**
* The Data.
*/
Item data;
/**
* The Next.
*/
Node<Item> next;
/**
* The Prev.
*/
Node<Item> prev;
/**
* Instantiates a new Node.
*
* #param data the data
*/
Node(Item data) {
this.data = data;
}
}
/**
* Instantiates a new Deque.
*/
public Deque() {
dequeSize = 0;
}
/**
* Is empty boolean.
*
* #return the boolean
*/
public boolean isEmpty() {
return dequeSize == 0;
}
/**
* Size int.
*
* #return the int
*/
public int size() {
return dequeSize;
}
/**
* Add first.
*
* #param item the item
*/
public void addFirst(Item item) {
if (item == null) {
throw new IllegalArgumentException();
}
Node<Item> newNode = new Node<Item>(item);
if (head == null) {
head = newNode;
tail = newNode;
} else {
head.prev = newNode;
newNode.next = head;
head = newNode;
}
dequeSize++;
}
/**
* Add last.
*
* #param item the item
*/
public void addLast(Item item) {
if (item == null) {
throw new IllegalArgumentException();
}
Node<Item> newNode = new Node<Item>(item);
if (head == null) {
head = newNode;
tail = newNode;
} else {
tail.next = newNode;
newNode.prev = tail;
tail = newNode;
}
dequeSize++;
}
/**
* Remove first item.
*
* #return the item
*/
public Item removeFirst() {
if (isEmpty()) {
throw new NoSuchElementException();
}
Item headData = head.data;
if (dequeSize == 1) {
head = null;
tail = null;
} else {
Node<Item> headNext = head.next;
headNext.prev = null;
head = headNext;
}
dequeSize--;
return headData;
}
/**
* Remove last item.
*
* #return the item
*/
public Item removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
Item tailData = tail.data;
if (dequeSize == 1) {
head = null;
tail = null;
} else {
Node<Item> tailPrev = tail.prev;
tailPrev.next = null;
tail = tailPrev;
}
dequeSize--;
return tailData;
}
/**
* Iterator iterator.
*
* #return the iterator
*/
public Iterator<Item> iterator() {
return new CustomIterator();
}
private class CustomIterator implements Iterator<Item> {
private Node<Item> temp;
/**
* Instantiates a new Custom iterator.
*/
CustomIterator() {
temp = head;
}
public boolean hasNext() {
return temp.next != null;
}
public Item next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Item tempData = temp.data;
temp = temp.next;
return tempData;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
/**
* The entry point of application.
*
* #param args the input arguments
*/
public static void main(String[] args) {
// unit testing (required)
}
}
As the title suggests, I am trying to Sort my ArrayList of objects, and those objects have implemented comparable and have overriden CompareTo
However when I got to sort my arraylist i get this error
I can't seem to understand why I am getting this problem? Can anybody help?
ItemList Class:
package stories.cs2800;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.AbstractListModel;
#SuppressWarnings("serial")
public class ItemList extends AbstractListModel<Item> {
private ArrayList<Item> items;
/**
* Constructor that initializes the array list.
*/
public ItemList() {
items = new ArrayList<Item>();
}
#Override
public int getSize() {
return items.size();
}
/**
* Method to get item based on the index.
* #param argIndex - Takes parameter of type int.
* #return Returns item at the index.
*/
#Override
public Item getElementAt(int argIndex) throws IndexOutOfBoundsException {
if (argIndex < 0 || argIndex >= items.size()) {
throw new IndexOutOfBoundsException();
}
return items.get(argIndex);
}
/**
* Method that gets and Item element based on the name.
*
* #param argName - takes parameter of type String.
* #return Returns the entire item object if name matches, else null.
*/
public Item getElementByName(String argName) {
for (Item i : items) {
if (i.getName().equals(argName)) {
return i;
}
}
return null;
}
/**
* Method to add another Item into the array list.
* #param Takes parameter of type item.
* #see ArrayList#add
*/
public void add(Item next) {
items.add(next);
Collections.sort(items);
}
/**
* Boolean method to check if list contains the item of type Item.
*
* #param Takes parameter of type item.
* #return returns boolean value of true or false if item is contained.
*/
public Boolean contains(Item argItem) {
return items.contains(argItem);
}
/**
* Boolean method remove to remove item of type Item from list.
*
* #param Takes parameter of type Item.
* #return returns boolean value of true or false if item is removed.
*/
public Boolean remove(Item argItem) {
return items.remove(argItem);
}
/**
* Boolean method that removes and item based on its index.
*
* #argIndex Takes a parameter of type int.
* #return returns boolean value of true or false if item was removed based on index.
*/
public Boolean remove(int argIndex) throws IndexOutOfBoundsException {
if (argIndex < 0 || argIndex >= items.size()) {
throw new IndexOutOfBoundsException();
}
return items.remove(items.get(argIndex));
}
/**
* Method to find the index of an item object.
*
* #param Takes parameter of type Item.
* #return Returns item index based on the item object entered.
*/
public int indexOf(Item argItem) {
return items.indexOf(argItem);
}
/**
* Method to check if item changed.
*
* #param Takes parameter of type Item.
*/
public void changed(Item argItem) {
fireContentsChanged(this, items.indexOf(items), items.indexOf(items));
/*Method called when one or more items have changed */
}
}
SingleItem Class:
package stories.cs2800
public class SingleItem implements Comparable<Item>, Item {
private String name;
private float value;
private Item child;
/**
* Constructor for the SingleItem object.
*
* #param argName Stores the name that is set in constructor
* #param argValue Stores the float value that is set in Constructor
* #param argChild Stores the value of the child element
*/
public SingleItem(String argName, float argValue, Item argChild) {
name = argName;
value = argValue;
child = argChild;
}
/**
* Getter method to get the value of the name variable.
*
* #return returns the name
*/
#Override
public String getName() {
return this.name;
}
/**
* Getter method to get the value of the Float variable.
*
* #return value set in the value variable
*
*/
#Override
public Float getValue() {
return this.value;
}
/**
* Setter method to set the value of the Float - No return type.
* #param argFloat - Takes parameter of type Float using Wrapper class.
*/
#Override
public void setValue(Float argFloat) {
this.value = argFloat;
}
/**
* Method to get the description.
*
* #return Returns the a string with the description
*/
#Override
public String getDescription() {
return "Single items have no description";
}
/**
* Getter method for child element.
*
* #return returns the value of child element
*/
public Item getChild() {
return this.child;
}
/**
* Method for adding items.
* #param child - Takes parameter of type Item.
* #return Returns Exception when child is null.
*
*/
#Override
public void add(Item child) {
if (this.child != null) {
throw new IllegalStateException();
}
this.child = child;
}
/**
* Method for ItemVisitor.
* #param argVisitor - Takes parameter of ItemVisitor to add current class.
* #return Currently no valid method!.
*
*/
#Override
public <T> void accept(ItemVisitor<T> argVisitor) {
argVisitor.add(this);
}
/**
* Method that takes Boolean as a parameter.
* #param argBool - Takes parameter of type boolean.
* #return Returns exception.
*/
#Override
public void open(boolean argBool) throws IllegalStateException {
throw new IllegalStateException();
}
/**
* Method that compares name to name entered as a parameter.
* #param item - Takes parameter of type item.
* #return Returns an int based on comparison of name. E.g. 0 = same, 1 = different.
*/
#Override
public int compareTo(Item item) {
return this.name.compareTo(item.getName());
}
/**
* Method to check if Open.
*
* #return Always returns true.
*/
#Override
public boolean isOpen() {
return true;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
SingleItem other = (SingleItem) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
/**
* toString method to get values of elements.
*
* #return Returns a sentence with the values of all elements.
*/
#Override
public String toString() {
return "Name: " + getName() + ", Value: " + getValue()
+ ", Description: "
+ getDescription();
}
}
In short, Item doesn't implement Comparable. And the list is a list of Item.
Details here. In the code above, items = new ArrayList<Item>();. Which means compiler only knows that in list items, the type is Item. So when invoke Collections.sort(items), java compiler found Item doesn't implement Comparable. And there will be an error as shown at the beginning.
How to fix? Change definition of Item, make it implement Comparable.
So as you can see, there is nothing about SingleItem. Because it is the impl and items sees only interface Item.