I look for a queue that stores up to N elements for a certain time (i.e. 10 sec) or should dispose the oldest value if full.
I found a similar queue in the Apache Collections (CircularFifoQueue JavaDoc) that misses the aspect of time to live. A full fletched message broker seems like an overhead for my small project.
Do you mind giving me a hint how I should implement this? Shall I filter out old values while I poll for elements?
There is a class called LinkedHashMap which has a special method for removing stale data. From the documentation:
protected boolean removeEldestEntry(Map.Entry eldest)
Returns true if this map should remove its eldest entry.
The method removeEldestEntry is called whenever anything is added to the list (queue). If it returns true then the eldest entry is removed to make room for the new entry, otherwise nothing is removed. You can add your own implementation which checks the timestamp on the eldest entry and returns true if it be older than a threshhold for expiration (e.g. 10 seconds). So your implementation might look something like this:
protected boolean removeEldestEntry(Map.Entry eldest) {
long currTimeMillis = System.currentTimeMillis();
long entryTimeMillis = eldest.getValue().getTimeCreation();
return (currTimeMillis - entryTimeMillis) > (1000*10*60);
}
I think java.util.LinkedHashMap is the solution for you. It has a removeEldest() method which is called whenever an entry is put in the map. You can override it to indicate if the eldest entry should be removed.
The JavaDoc gives a good example:
private static final int MAX_ENTRIES = 100;
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_ENTRIES;
}
This removes the eldest entry if the map has more than 100 entries.
Pro-actively removing items after 10 seconds would require a separate thread to check age and remove old items. I am guessing this is not what you want, judging by your description.
I used to following queue implementation. The code is heavily based on Apaches CircularFifoQueue and is only weakly tested. Moreover the implementation is not thread-safe and not serializable.
Leave a comment if you spot a mistake.
import java.util.AbstractCollection;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
/**
* TimedQueue is a first-in first-out queue with a fixed size that
* replaces its oldest element if full.
* <p>
* The removal order of a {#link TimedQueue} is based on the
* insertion order; elements are removed in the same order in which they
* were added. The iteration order is the same as the removal order.
* <p>
* The {#link #add(Object)}, {#link #remove()}, {#link #peek()}, {#link #poll},
* {#link #offer(Object)} operations all perform in constant time.
* All other operations perform in linear time or worse.
* <p>
* This queue prevents null objects from being added and it is not thread-safe and not serializable.
*
* The majority of this source code was copied from Apaches {#link CircularFifoQueue}: http://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/queue/CircularFifoQueue.html
*
* #version 1.0
*/
public class TimedQueue<E> extends AbstractCollection<E>
implements Queue<E> {
/** Underlying storage array. */
private Item<E>[] elements;
/** Array index of first (oldest) queue element. */
private int start = 0;
/**
* Index mod maxElements of the array position following the last queue
* element. Queue elements start at elements[start] and "wrap around"
* elements[maxElements-1], ending at elements[decrement(end)].
* For example, elements = {c,a,b}, start=1, end=1 corresponds to
* the queue [a,b,c].
*/
private transient int end = 0;
/** Flag to indicate if the queue is currently full. */
private transient boolean full = false;
/** Capacity of the queue. */
private final int maxElements;
private TimeUnit unit;
private int delay;
/**
* Constructor that creates a queue with the default size of 32.
*/
public TimedQueue() {
this(32);
}
/**
* Constructor that creates a queue with the specified size.
*
* #param size the size of the queue (cannot be changed)
* #throws IllegalArgumentException if the size is < 1
*/
public TimedQueue(final int size) {
this(size, 3, TimeUnit.SECONDS);
}
#SuppressWarnings("unchecked")
public TimedQueue(final int size, int delay, TimeUnit unit) {
if (size <= 0) {
throw new IllegalArgumentException("The size must be greater than 0");
}
elements = new Item[size];
maxElements = elements.length;
this.unit = unit;
this.delay = delay;
}
/**
* Constructor that creates a queue from the specified collection.
* The collection size also sets the queue size.
*
* #param coll the collection to copy into the queue, may not be null
* #throws NullPointerException if the collection is null
*/
public TimedQueue(final Collection<? extends E> coll) {
this(coll.size());
addAll(coll);
}
/**
* Returns the number of elements stored in the queue.
*
* #return this queue's size
*/
#Override
public int size() {
int size = 0;
for(int i = 0; i < elements.length; i++) {
if(validElement(i) != null) {
size++;
}
}
return size;
}
/**
* Returns true if this queue is empty; false otherwise.
*
* #return true if this queue is empty
*/
#Override
public boolean isEmpty() {
return size() == 0;
}
private boolean isAtFullCapacity() {
return size() == maxElements;
}
/**
* Clears this queue.
*/
#Override
public void clear() {
full = false;
start = 0;
end = 0;
Arrays.fill(elements, null);
}
/**
* Adds the given element to this queue. If the queue is full, the least recently added
* element is discarded so that a new element can be inserted.
*
* #param element the element to add
* #return true, always
* #throws NullPointerException if the given element is null
*/
#Override
public boolean add(final E element) {
if (null == element) {
throw new NullPointerException("Attempted to add null object to queue");
}
if (isAtFullCapacity()) {
remove();
}
elements[end++] = new Item<E>(element);
if (end >= maxElements) {
end = 0;
}
if (end == start) {
full = true;
}
return true;
}
/**
* Returns the element at the specified position in this queue.
*
* #param index the position of the element in the queue
* #return the element at position {#code index}
* #throws NoSuchElementException if the requested position is outside the range [0, size)
*/
public E get(final int index) {
final int sz = size();
if (sz == 0) {
throw new NoSuchElementException(
String.format("The specified index (%1$d) is outside the available range because the queue is empty.", Integer.valueOf(index)));
}
if (index < 0 || index >= sz) {
throw new NoSuchElementException(
String.format("The specified index (%1$d) is outside the available range [0, %2$d]",
Integer.valueOf(index), Integer.valueOf(sz-1)));
}
final int idx = (start + index) % maxElements;
return validElement(idx);
}
private E validElement(int idx) {
if(elements[idx] == null){
return null;
}
long diff = System.currentTimeMillis() - elements[idx].getCreationTime();
if(diff < unit.toMillis(delay)) {
return (E) elements[idx].getValue();
} else {
elements[idx] = null;
return null;
}
}
//-----------------------------------------------------------------------
/**
* Adds the given element to this queue. If the queue is full, the least recently added
* element is discarded so that a new element can be inserted.
*
* #param element the element to add
* #return true, always
* #throws NullPointerException if the given element is null
*/
public boolean offer(E element) {
return add(element);
}
public E poll() {
if (isEmpty()) {
return null;
}
return remove();
}
public E element() {
if (isEmpty()) {
throw new NoSuchElementException("queue is empty");
}
return peek();
}
public E peek() {
if (isEmpty()) {
return null;
}
return (E) elements[start].getValue();
}
public E remove() {
if (isEmpty()) {
throw new NoSuchElementException("queue is empty");
}
final E element = validElement(start);
if (null != element) {
elements[start++] = null;
if (start >= maxElements) {
start = 0;
}
full = false;
}
return element;
}
/**
* Increments the internal index.
*
* #param index the index to increment
* #return the updated index
*/
private int increment(int index) {
index++;
if (index >= maxElements) {
index = 0;
}
return index;
}
/**
* Decrements the internal index.
*
* #param index the index to decrement
* #return the updated index
*/
private int decrement(int index) {
index--;
if (index < 0) {
index = maxElements - 1;
}
return index;
}
/**
* Returns an iterator over this queue's elements.
*
* #return an iterator over this queue's elements
*/
#Override
public Iterator<E> iterator() {
return new Iterator<E>() {
private int index = start;
private int lastReturnedIndex = -1;
private boolean isFirst = full;
public boolean hasNext() {
return (isFirst || index != end) && size() > 0;
}
public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
isFirst = false;
lastReturnedIndex = index;
index = increment(index);
if(validElement(lastReturnedIndex) == null) {
return next();
} else {
return validElement(lastReturnedIndex);
}
}
public void remove() {
if (lastReturnedIndex == -1) {
throw new IllegalStateException();
}
// First element can be removed quickly
if (lastReturnedIndex == start) {
TimedQueue.this.remove();
lastReturnedIndex = -1;
return;
}
int pos = lastReturnedIndex + 1;
if (start < lastReturnedIndex && pos < end) {
// shift in one part
System.arraycopy(elements, pos, elements, lastReturnedIndex, end - pos);
} else {
// Other elements require us to shift the subsequent elements
while (pos != end) {
if (pos >= maxElements) {
elements[pos - 1] = elements[0];
pos = 0;
} else {
elements[decrement(pos)] = elements[pos];
pos = increment(pos);
}
}
}
lastReturnedIndex = -1;
end = decrement(end);
elements[end] = null;
full = false;
index = decrement(index);
}
};
}
private static final class Item<E> {
private long creationTime;
private E in;
public Item(E in) {
this.in = in;
creationTime = System.currentTimeMillis();
}
public E getValue() {
return in;
}
public long getCreationTime() {
return creationTime;
}
}
}
Related
I have one test that is not going through in this testclass. I have implemented the code that I have tried, however it is not working. I dont know what I am doing wrong. I think that my Hashtable code is correct however, this test does not work.
//TODO: How should I write this test in the testclass.
The message I get is :
java.lang.AssertionError:
Expected: <7>
but: was <0>
Expected :<7>
Actual :<0>
/**
* An interface describing a generic set. Duplicates are not allowed.
*/
public interface Set<T> {
boolean add(T elem);
boolean remove(T elem);
boolean contains(T elem);
int size();
}
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import static java.util.Objects.hash;
/**
* A hash table-based implementation of the Set interface.
*/
public class HashSet<T> implements Set<T> {
private List<T>[] table;
private int size;
private int capacity;
private int index;
/**
* Creates a hash table with the given capacity (amount of buckets).
*
* #throws IllegalArgumentException if capacity <= 0.
*/
public HashSet(int capacity) {
if (capacity <= 0) {
throw new IllegalArgumentException(
"capacity must be a positive, non-zero value! Provided: " + capacity);
}
#SuppressWarnings("unchecked") // for this declaration only
List<T>[] t = new LinkedList[capacity];
table = t;
size = 0;
}
/**
* Adds the given element to the set.
*
* Complexity: O(1) expected time.
*
* #param elem An element to add to the set.
* #return true if the set did not contain the element, otherwise false.
*/
#Override
public boolean add(T elem) {
if (elem == null || elem.equals("")){
return false;
}
int hash = Math.abs(elem.hashCode() % table.length);
if (table[hash]== null){
table[hash] = new LinkedList<T>();
table[hash].add(elem);
size ++;
return true;
}
if (table[hash].contains(elem)){
return false;
}else{
table[hash].add(elem);
size++;
return true;
}
}
/**
* Removes the given element from the dictionary, if it is present.
*
* Complexity: O(1) expected time.
*
* #param elem An element to remove from the set.
* #return true if the set contained the element, false otherwise.
*/
#Override
public boolean remove(T elem) {
if (elem == null || elem.equals("")){
return false;
}
int hash = Math.abs(elem.hashCode() % table.length);
if (table[hash] != null && table[hash].contains(elem)){
table[hash].remove(elem);
size --;
return true;
}else{
return false;
}
}
/**
* Check if an element is in the Set.
*
* Complexity: O(1) expected time.
*
* #param elem An element to look for.
* #return true if the element is in the set, false otherwise.
*/
#Override
public boolean contains(T elem) {
if (elem == null || elem .equals("")){
return false;
}
int hash = Math.abs(elem.hashCode() % table.length);
if (table[hash] != null && table[hash].contains(elem)){
return true;
}else{
return false;
}
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
HashSet<?> hashSet = (HashSet<?>) o;
return capacity == hashSet.capacity && size == hashSet.size && index == hashSet.index && Objects.equals(table, hashSet.table);
}
#Override
public int hashCode() {
return hash(capacity, size, index, table);
}
/**
* Returns the number of elements in this set.
*
* Complexity: O(1) expected time.
*
* #return The amount of elements in this set.
*/
#Override
public int size() {
return size;
}
}
import org.junit.Test;
import org.junit.Before;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.rules.Timeout;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.*;
import java.util.Arrays;
import java.util.EmptyStackException;
import java.util.stream.IntStream;
/**
* Abstract test class for Set implementations.
*
* Implementing test classes must override the getIntegerSet method.
*
*/
public abstract class SetTest {
#Rule public Timeout globalTimeout = Timeout.seconds(5); // 5 seconds max per method tested
private Set<Integer> set;
private final int CAPACITY = 20;
private int[] uniqueSetElements;
private int[] elementsNotInSet;
/**
* Returns an implementation of Set that can hold at least 'minCapacity'
* Integers.
*
* #param minCapacity The least amount of elements the Set must be able to
* hold.
* #return An implementation of Set.
*/
protected abstract Set<Integer> getIntegerSet(int minCapacity);
#Before
public void setUp() {
// Arrange
set = getIntegerSet(CAPACITY);
uniqueSetElements =
new int[] {-234, 32, 443, Integer.MAX_VALUE, Integer.MIN_VALUE, 0, -231};
// Works because all elements in uniqueSetElements are more than 2 values apart
// -2 as Integer.MIN_VALUE - 1 == Integer.MAX_VALUE because of underflow
elementsNotInSet = Arrays.stream(uniqueSetElements).map(elem -> elem - 2).toArray();
for (int elem : uniqueSetElements) {
set.add(elem);
}
}
#Test
public void removeElementsInSetDecrementsSize() { //TEST
int expectedSize = uniqueSetElements.length;
for (int elem : uniqueSetElements) {
// Act
set.remove(elem);
}
assertThat(set.size(), equalTo(expectedSize));
}
}
You are removing all elements from the set and still expecting the size to be the original size. Set expectedSize to 0 and it would be fine.
#Test
public void removeElementsInSetDecrementsSize() { //TEST
int expectedSize = 0;
for (int elem : uniqueSetElements) {
// Act
set.remove(elem);
}
assertThat(set.size(), equalTo(expectedSize));
}
I want to instantiate each element of my ArrayList of type LinkedQueue (size 26, one queue for each letter of the alphabet). Off the top of my head -- because I haven't worked with LinkedQueues very much, I wrote this:
public void initializeList() {
ArrayList<LinkedQueue> arrayList = new ArrayList<LinkedQueue>();
String letters = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < letters.length(); i++){
arrayList.add(letters.charAt(i));
}
}
But I get an error that says: "The method add(LinkedQueue) in the type ArrayList is not applicable for the arguments (char)." I still haven't completely mastered Java; could someone help me understand what this means and what I'm doing wrong (or possible recommend a better solution)?
For reference, this is the LinkedQueue class:
public class LinkedQueue<T> implements QueueADT<T>
{
private int count;
private LinearNode<T> head, tail;
/**
* Creates an empty queue.
*/
public LinkedQueue()
{
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 enqueue(T element)
{
LinearNode<T> node = new LinearNode<T>(element);
if (isEmpty())
head = node;
else
tail.setNext(node);
tail = node;
count++;
}
/**
* 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 dequeue() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("queue");
T result = head.getElement();
head = head.getNext();
count--;
if (isEmpty())
tail = null;
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("Queue is empty");
return head.getElement();
}
/**
* Returns true if this queue is empty and false otherwise.
* #return true if this queue is empty
*/
public boolean isEmpty()
{
return count==0;
}
/**
* 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.
* #return the string representation of the queue
*/
public String toString()
{
StringBuilder s = new StringBuilder("");
LinearNode<T> current = head;
while (current != null) {
s.append(current.getElement());
s.append("\n");
current = current.getNext();
}
return s.toString();
}
/**
* Returns true if the list in the parameter has the same length and data elements
* as "this" Linked Queue. Returns false otherwise.
* #return true if the lists are equal
*/
#Override
public boolean equals(LinkedQueue<T> list) {
// Lab exercise 1. Fill in this method.
return true;
}
/**
* Returns a LinkedQueue that contains the same data elements as "this", but in
* reverse order
* #return a LinkedQueue that is the reverse of this queue
*/
public LinkedQueue<T> reverse() {
// Lab exercise 2. Fill in this method.
return null;
}
}
I keep getting an ArrayStoreError when I use my PriorityQueItem.add(E item) method. The flow of my code is...
if (student.deductCoins(coins)) { //if the student has enough coins...
PriorityQueueItem<Student> newPQI = new PriorityQueueItem<Student>
(coins); //...create a new PriorityQueueItem<E> object
// using that amount for the priority
newPQI.add(student); //add the student to the queue associated with this
//PriorityQueueItem object
...in the Course class and then my PriorityQueItem.add(E item) is...
public void add(E item) {getList().enqueue(item);}
...which uses the Queue<E>.enqueue(E item) method to add the add to the queue of new PriorityQueueItem<E>. Each PriorityQueueItem has an integer value and a Queue<E> queue assigned to it on creation; getList() gets the queue.
Based on the stack trace, the error is triggered when the line queue[front]=item in Queue<E>.enqueue(E item) is reached. According to the API, the ArrayStoreException occurs when you try to add the wrong type of an item to an array but I cannot see where in this sequence where it happens. Any help will be appreciated.
#Erin and #Thomas:
/**
*
* Class to represent object stored at every entry in the PriorityQueue. ie, The
* internal node structure of {#link PriorityQueue}
*
* #author CS367
*
* #param
* the generic type of the data content stored in the list
*/
public class PriorityQueueItem implements Comparable> {
private int priority;
private Queue<E> queue;
public PriorityQueueItem(int priority) {
this.priority = priority;
this.queue = new Queue<E>();
}
public int getPriority() {
// TODO
return this.priority;
}
public Queue<E> getList() {
// TODO
return this.queue;
}
/**
* Add an item to the queue of this PriorityQueueItem object
* #param
*
* #param student
* item to add to the queue
*/
public void add(E item) {
getList().enqueue(item);
}
/**
* Compares this Node to another node on basis of priority
*
* #param o
* other node to compare to
* #return -1 if this node's priority is lesser, +1 if this nodes priority
* is higher after, else 0 if priorities are the same.
*/
#Override
public int compareTo(PriorityQueueItem<E> o) {
int x = 0;
if (this.getPriority() > o.getPriority())
x = 1;
if (this.getPriority() == o.getPriority())
x = 0;
if (this.getPriority() < o.getPriority())
x = 1;
return x;
}
}
/**
* An ordered collection of items, where items are added to the rear and removed
* from the front.
*/
public class Queue implements QueueADT {
private static final int MAX_CAPACITY = 100;
private E[] queue;
private int size;
private int front;
private int rear;
// TODO
// You may use a naive expandable circular array or a chain of listnodes.
// You may NOT use Java's predefined classes such as ArrayList or
// LinkedList.
#SuppressWarnings("unchecked")
public Queue() {
this.queue = (E[]) new Array [MAX_CAPACITY];
this.size = 0;
this.front = 0;
this.rear = 0;
}
/**
* Adds an item to the rear of the queue.
*
* #param item
* the item to add to the queue.
* #throws IllegalArgumentException
* if item is null.
*/
public void enqueue(E item) {
if (item == null) {
throw new IllegalArgumentException();
}
// if number of items exceeds size limits of the array
// then expand the array
if (!(size < queue.length - 1)) {
this.expandCapacity();
}
queue[rear] = item;
if (rear < queue.length - 1) {
rear++;
} else {
rear = 0;
}
size++;
}
/**
* Removes an item from the front of the Queue and returns it.
*
* #return the front item in the queue.
* #throws EmptyQueueException
* if the queue is empty.
*/
public E dequeue() {
if (isEmpty()) {
throw new EmptyQueueException();
}
E next = this.queue[front];
queue[front] = null;
if (this.front < queue.length - 1) {
this.front++;
} else {
this.front = 0;
}
size--;
return next;
}
/**
* Returns the item at front of the Queue without removing it.
*
* #return the front item in the queue.
* #throws EmptyQueueException
* if the queue is empty.
*/
public E peek() {
return this.queue[front];
}
/**
* Returns true iff the Queue is empty.
*
* #return true if queue is empty; otherwise false.
*/
public boolean isEmpty() {
return this.size == 0;
}
/**
* Removes all items in the queue leaving an empty queue.
*/
public void clear() {
while (!isEmpty()) {
this.dequeue();
}
}
/**
* Returns the number of items in the Queue.
*
* #return the size of the queue.
*/
public int size() {
return this.size;
}
#SuppressWarnings("unchecked")
private void expandCapacity() {
E[] newQueue;
newQueue = (E[]) Array.newInstance(PriorityQueueItem.class,
this.size() * 2);
for (int i = 0; i < queue.length; i++) {
newQueue[i] = this.queue[i];
}
this.queue = newQueue;
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
I just want to make sure what I am receiving from an Eclipse is an error, or it's fine?
Here is my code:
package prj2;
public class Sandbox {
public static void main(String[] args) {
NodeChain<Integer> myList = new NodeChain<Integer>();
myList.add(1);
myList.add(2);
myList.add(0, -99);
myList.add(3, 45);
myList.add(99);
myList.add(4, 50);
myList.remove(0);
myList.remove(3);
myList.remove(1);
System.out.println(myList.contains(45));
myList.print();
System.out.println("myList has size "+myList.size());
}
}
And here is the result:
Exception in thread "main" java.lang.NullPointerException
at prj2.NodeChain.contains(NodeChain.java:57)
at prj2.Sandbox.main(Sandbox.java:18)
If that's an error can you please help for a fix?
Source for NodeChain:
package prj2;
public class NodeChain<E> implements ListADT<E>{
private ListNode<E> head; // this is a dummy header
private ListNode<E> tail;
private int numItems;
public NodeChain() {
head = new ListNode<E>(null);
tail = head;
numItems = 0;
}
public boolean isEmpty() { return numItems == 0; }
public void add(E item) {
// Note the lack of a need for null checks
tail.setNext(new ListNode<E>(item, tail.getNext()));
tail = tail.getNext();
numItems++;
}
public void add(int pos, E item) {
// Handle the cases where an invalid pos is given
if (pos < 0 || pos > numItems) throw new IndexOutOfBoundsException();
// Handle the case where we're adding to the end of the list.
if (pos == numItems) {
add(item);
return;
}
// No other special case handling required
// Traverse the list until we get to the point of insertion and execute the insertion.
ListNode<E> tmp = traverseTo(pos);
tmp.setNext(new ListNode<E>(item, tmp.getNext()));
// Increment numItems
numItems++;
}
public int size() { return numItems; }
public E remove(int pos) { // Left unimplemented
return null;
}
public E get(int pos) {
if (pos < 0 || pos >= numItems) throw new IndexOutOfBoundsException();
ListNode<E> node = traverseTo(pos+1);
return node.getData();
}
public boolean contains(E obj) {
ListNode<E> tmp = head;
while (tmp != null) {
if (tmp.getData().equals(obj)) return true;
tmp = tmp.getNext();
}
return false;
}
private ListNode<E> traverseTo(int pos) {
if (pos < 0 || pos >= numItems) throw new IndexOutOfBoundsException();
ListNode<E> tmp = head;
for (int i = 0; i < pos; i++)
tmp = tmp.getNext();
return tmp;
}
/* Extra method to facilitate debugging */
public void print() {
ListNode<E> tmp = head;
while (tmp != null) {
System.out.print(tmp.getData()+", ");
tmp = tmp.getNext();
}
System.out.println();
}
}
Source for ListNode:
package prj2;
public class ListNode<T> {
private T data;
private ListNode<T> next;
public ListNode(T obj) {
this(obj, null);
}
public ListNode(T obj, ListNode<T> ptr) {
data = obj;
next = ptr;
}
public void setData(T obj) { data = obj; }
public T getData() { return data; }
public void setNext(ListNode<T> n) { next = n; }
public ListNode<T> getNext() { return next; }
}
Source for ListADT:
package prj2;
/**
* A List is an ordered collection of items.
*/
public interface ListADT<E> {
/**
* Add item to the end of the List.
*
* #param item the item to add
*/
void add(E item);
/**
* Add item at position pos in the List, moving the items
* originally in positions pos through size()- 1 one place
* to the right to make room.
*
* #param pos the position at which to add the item
* #param item the item to add
* #throws IndexOutOfBoundsException if pos is less than 0
* or greater than size()
*/
void add(int pos, E item);
/**
* Return true iff item is
* item x in the List such
*
* #param item the item to
* #return true if item is
*/
boolean contains(E item);
/**
* Return the number of items in the List.
*
* #return the number of items in the List
*/
int size();
/**
* Return true iff the List is empty.
*
* #return true if the List is empty, false otherwise
*/
boolean isEmpty();
/**
* Return the item at position pos in the List.
*
* #param pos the position of the item to return
* #return the item at position pos
* #throws IndexOutOfBoundsException if pos is less than 0
* or greater than or equal to size()
*/
E get(int pos);
/**
* Remove and return the item at position pos in the List,
* moving the items originally in positions pos+1 through
* size() one place to the left to fill in the gap.
*
* #param pos the position at which to remove the item
* #return the item at position pos
* #throws IndexOutOfBoundsException if pos is less than 0
* or greater than or equal to size()
*/
E remove(int pos);
}
Well,it is clearly reflected from the output that it's an Exception thrown or rather Error.The exception thrown is java.lang.NullPointerException!
Also,the stack trace of what the error is about is printed below the Exception thrown line:-
at prj2.NodeChain.contains(NodeChain.java:57)
at prj2.Sandbox.main(Sandbox.java:18)
Also,it's clearly visible from your stack trace that there is an exception being thrown at System.out.println(myList.contains(45));.
You better resolve this error after checking your code of contains() method in NodeClass Class!
Hey everybody I'm working with Java.
So I am writing a class called OrderedSet. It is a class that is cross between a set and a queue. In other words, it is a queue without any duplicates. So I know I have to implement the Iterable interface, and write an iterator method. To write the method I have to then implement the Iterator interface.
package comp345;
import java.util.Iterator;
import java.util.NoSuchElementException;
class OrderedSet implements Iterable<Object> {
private Object[] queue; // This is how the OrderedSet is represented, a
// queue of Objects
private int counter; // Counter to keep track of current position of queue
private int queueSize; // Keep track of the queue;
// Constructor
public OrderedSet(int size) {
this.queue = new Object[size];
this.counter = 0;
this.queueSize = size - 1;
// Instantiate each instance of the object in the object array
for (int i = 0; i < queue.length; i++) {
queue[i] = new Object();
}
}
/**
* Ensures that this collection contains the specified element. If it is not
* already in the collection it is added it to the back of the queue.
*
* #param e
* element whose presence in this collection is to be ensured
* #return true if this collection changed as a result of the call
* #throws NullPointerException
* if the specified element is null
*/
boolean add(Object i) {
if (i == queue[counter]) {
return false;
} else if (i == null)
throw new NullPointerException();
else {
// Add Object to back of Queue
queue[counter] = i;
return true;
}
}
/**
* Removes all of the elements from this collection. The collection will be
* empty after this method returns.
*/
void clear() {
for (int i = 0; i < queue.length; i++) {
queue[i] = null;
}
}
/**
* Returns true if this collection contains no elements.
*
* #return true if this collection contains no elements
*/
boolean isEmpty() {
if (queue[0] == null)
return true;
else
return false;
}
/**
* Retrieves, but does not remove, the head of this queue, or returns null
* if this queue is empty
*
* #return the head of this queue, or null if this queue is empty
*/
Object peek() {
if (queue[counter] != null)
return queue[counter];
else
return null;
}
/**
* Retrieves and removes the head of the queue.
*
* #return the head of this queue
* #throws NoSuchElementException
* if this queue is empty
*/
Object remove() {
if (queue[0] != null) {
Object temp = queue[0];
queue[0] = queue[1];
return temp;
} else
throw new NoSuchElementException();
}
public class SetIterator implements Iterator<Object> {
private int counter;
public SetIterator() {
this.counter = 0;
}
#Override
public Object next() {
counter++;
if (queueSize == counter)
return null;
else if (queue[counter] != null)
return (Object) queue[counter];
else
throw new NoSuchElementException();
}
#Override
public boolean hasNext() {
counter++;
if (queueSize < counter)
return false;
else if (queue[counter] != null)
return true;
return false;
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
#Override
public Iterator<Object> iterator() {
return new SetIterator();
}
public static void main(String args[]) {
OrderedSet os;
os.add("hello");
os.add(4);
os.add("bye");
for (Object o : os) {
System.out.println(o);
}
}
}
I can see at least one problem.
Take a closer look at your hasNext() method.
Do you really want to increment the variable counter?
The problem with your code is here:
OrderedSet os;
os.add("hello");
You have declared a reference of os, but you haven't assigned it anything. The compiler won't allow this. You have to do:
OrderedSet os = new OrderedSet(10);
There are other problems with your code (#hallidave found one) but that is the first problem.
In general when you have a problem with an error, you should ask with more information than "it doesn't work." The exact error message will go a long way to answering the question. I know compiler error messages don't mean much to you yet, but when you get more experience they will.