I am getting the following error when I'm compiling my code...
BSLinkedList.java:10: error: BSLinkedList is not abstract and does not override abstract method push(T) in BoundedStack
public class BSLinkedList <T> implements BoundedStack<T>{
^
where T is a type-variable:
T extends Object declared in class BSLinkedList
I have tried to make sure that everything I am using is generic type T. All of the questions I've found on this topic say that people have not implemented a method from the interface, however I have implemented the method push as well as all other methods from my interface! I appreciate any help or guidance anyone can supply! Thank you!
import java.util.EmptyStackException;
import java.util.*;
/**
* The class BSLinkedList implements the Stack ADT as described
* in cpsc331Stack using a linked list
*
* #version 1.0
*/
public class BSLinkedList <T> implements BoundedStack<T>{
public class StackNode<T> {
private T value;
public StackNode<T> next;
private int capacity;
public StackNode<T> top;
private int size;
public StackNode(T x, StackNode<T> n){
value = x;
next = n;
}
public void BSLinkedList(int capacity) {
assert capacity >= 0;
LinkedList<T> stack = new LinkedList<T>();
size = 0;
top = (StackNode<T>)null;
}
public boolean isEmpty(){
assert size >= 0;
if (size == 0){
return true;
}
else{
return false;
}
}
public boolean isFull(){
if (size == capacity){
return true;
}
else{
return false;
}
}
public int capacity(){
return capacity;
}
public int size(){
return size;
}
public void push(T x) {
if (isFull()){
throw new FullStackException();
}
else{
++size;
top = new StackNode<T>(x, top);
}
}
public T top(){
if(isEmpty()){
throw new EmptyStackException();
}
else{
return top.value;
}
}
public T pop(){
if (isEmpty()){
throw new EmptyStackException();
}
else{
T e = top.value;
top = top.next;
--size;
return e;
}
}
}
}
and the interface...
/**
* The BoundedStack interface represents the Bounded Stack ADT as described in CPSC 331.
* This interface extends the interface cpsc331Stack.
*
* #version 1.0
*/
public interface BoundedStack<T> extends cpsc331Stack<T>{
/**
* Returns the number of elements currently on the stack.
*
* #return the number of elements on the stack
*/
public int size();
/**
* Returns the maximum number of elements the stack can store.
*
* #return the maximum number of elements the stack can store
*/
public int capacity();
/**
* Tests whether the stack is full.
*
* #return true if number of elements in the stack is equal to
* the stack's capacity, false otherwise
*/
public boolean isFull();
/**
* Pushes the object x onto the top of the stack.
*
* #param x object to be pushed onto the stack.
* #throws FullStackException if the stack is full
*/
public void push (T x);
}
Other implementation that is working correctly...
import java.util.EmptyStackException;
/**
* The class BSArray implements the Stack ADT as described
* in cpsc331Stack using an array
*
* #version 1.0
*/
public class BSArray <T> implements BoundedStack<T>{
private T[] stack;
private int size;
private int top = -1;;
private int capacity;
/**
* Creates a new BSArray of size capacity
*
* #param capacity integer value of the maximum number of elements the array can store
*/
public BSArray(int capacity) {
assert capacity >= 0;
stack = (T[]) new Object[capacity];
}
/**
* Tests whether or not the stack is empty.
*
* #return true if the stack is empty, false otherwise
*/
public boolean isEmpty(){
if (size >= 0){
return true;
}
else{
return false;
}
}
/**
* Tests whether or not the stack is full.
*
* #return true if number of elements in the stack is equal to
* the stack's capacity, false otherwise
*/
public boolean isFull(){
if (size == capacity){
return true;
}
else{
return false;
}
}
/**
* Returns the maximum number of elements the stack can store.
*
* #return the maximum number of elements the stack can store
*/
public int capacity(){
return capacity;
}
/**
* Returns the number of elements currently on the stack.
*
* #return the number of elements on the stack
*/
public int size(){
return size;
}
/**
* Pushes the object x onto the top of the stack.
*
* #param x object to be pushed onto the stack.
* #throws FullStackException if the stack is full
*/
public void push(T x){
if (isFull()){
throw new FullStackException();
}
else{
++top;
++size;
stack[top] = x;
}
}
/**
* Returns the object at the top of the stack.
*
* #return reference to the item at the top of the stack
* #throws EmptyStackException if the stack is empty
*/
public T top(){
if(isEmpty()){
throw new EmptyStackException();
}
else{
return (T) stack[top];
}
}
/**
* Removes and returns the object at the top of the stack.
*
* #return reference to the item at the top of the stack
* #throws EmptyStackException if the stack is empty
*/
public T pop(){
if (isEmpty()){
throw new EmptyStackException();
}
else{
assert top >= -1;
T e = stack[top];
stack[top] = null;
--top;
--size;
return e;
}
}
}
cpsc331Stack interface
/**
* The cpsc331Stack interface represents the Stack ADT as described
* in CPSC 331.
*
* #version 1.0
*/
public interface cpsc331Stack<T> {
/**
* Tests whether the stack is empty.
*
* #return true if the stack is empty, false otherwise
*/
public boolean isEmpty();
/**
* Pushes the object x onto the top of the stack.
*
* #param x object to be pushed onto the stack.
*/
public void push(T x);
/**
* Returns the object at the top of the stack.
*
* #return reference to the item at the top of the stack
* #throws EmptyStackException if the stack is empty
*/
public T top();
/**
* Removes and returns the object at the top of the stack.
*
* #return reference to the item at the top of the stack
* #throws EmptyStackException if the stack is empty
*/
public T pop();
}
This is a bit speculative, but I believe the problem you are seeing is because your push() method does not actually override the exact signature you specified in your interface. You have this:
public void push(T x) throws FullStackException { }
but the interface has this:
public void push (T x);
For a quick fix, you can update the interface to throw the FullStackException.
By the way, the error you are seeing is a standard Java 101 error which occurs when you extend an abstract class without overriding all the abstract methods contained within that class. So your compiler thinks that there is an abstract method push() out there which you never overrode (even though you did, at least functionally speaking).
You have implemented the methods in the StackNode inner class but it is the outer class BSLinkedList which implements the interface.
In addition, as mentioned in the previous answer the push method declares an exception that is not in the interface method signature. This will result in an different error when you fix other issue.
**Edit in your second example you are have correctly implemented the methods in the class that implements the interface (you do not have the inner class).
Is this what you are trying to achieve?
/**
* The class BSLinkedList implements the Stack ADT as described
* in cpsc331Stack using a linked list
*
* #version 1.0
*/
public class BSLinkedList<T> implements BoundedStack<T> {
private int capacity;
public StackNode<T> top;
private int size;
public void BSLinkedList(int capacity) {
assert capacity >= 0;
LinkedList<T> stack = new LinkedList<T>();
size = 0;
top = null;
}
public boolean isEmpty() {
assert size >= 0;
if (size == 0) {
return true;
} else {
return false;
}
}
public boolean isFull() {
if (size == capacity) {
return true;
} else {
return false;
}
}
public int capacity() {
return capacity;
}
public int size() {
return size;
}
#Override
public void push(T x) {
if (isFull()) {
throw new FullStackException();
} else {
++size;
top = new StackNode<T>(x, top);
}
}
public T top() {
if (isEmpty()) {
throw new EmptyStackException();
} else {
return top.value;
}
}
public T pop() {
if (isEmpty()) {
throw new EmptyStackException();
} else {
T e = top.value;
top = top.next;
--size;
return e;
}
}
public class StackNode<T> {
private T value;
public StackNode<T> next;
public StackNode(T x, StackNode<T> n) {
value = x;
next = n;
}
}
}
Your method signature should match exactly with the method it is overriding. So, either remove the throws Exception from push method of BSLinkedList class or add the throws exception in the push method of BoundedStack interface.
Moreover, your class overrides all the methods of the BoundedStack interface. However, there may be certain methods which are defined in cpsc331Stack which you have to implement in your class.
Kindly post the source code of cpsc331Stack interface here so that we can help you better
You have actually defined the methods size(),capacity(),isFull(),push() inside the innerclass "StackNode" which is defined inside "BSLinkedList".If that is what you were actually intending,then "StackNode" class should implement "BoundedStack" instead of "BSLinkedList" implementing "BoundStack",else the method should be defined inside "BSLinkedList".
`class BSLinkedList <T>{
public class StackNode<T> implements BoundedStack<T>{
private T value;
public StackNode<T> next;
private int capacity;
public StackNode<T> top;
private int size;
public StackNode(T x, StackNode<T> n){
value = x;
next = n;
}
public void BSLinkedList(int capacity) {
assert capacity >= 0;
LinkedList<T> stack = new LinkedList<T>();
size = 0;
top = (StackNode<T>)null;
}
public boolean isEmpty(){
assert size >= 0;
if (size == 0){
return true;
}
else{
return false;
}
}
#Override
public boolean isFull(){
if (size == capacity){
return true;
}
else{
return false;
}
}
#Override
public int capacity(){
return capacity;
}
#Override
public int size(){
return size;
}
#Override
public void push(T x) {
if (isFull()){
throw new FullStackException();
}
else{
++size;
top = new StackNode<T>(x, top);
}
}
public T top(){
if(isEmpty()){
throw new EmptyStackException();
}
else{
return top.value;
}
}
public T pop(){
if (isEmpty()){
throw new EmptyStackException();
}
else{
T e = top.value;
top = top.next;
--size;
return e;
}
}
}
}`
Related
addAll at index, iterator set methods
Based on the lectures this week, we implemented ArrayList -- an order-dependent collection that grows as more data is added to it. Overall, it was based on an underlying array. However, two methods were left unimplemented: ArrayList.addAll(int index, Collection<? extends E>) and ArrayListIterator.set(E element). In this problem you are to implement those methods. A suite of test cases is provided. Consulting the documentation for List and ListIterator may be helpful.
You should not need access to any private fields, but based on the presentation in class, the following data and methods have been made protected instead of private so that you may access them:
public class ArrayList<E> extends AbstractList<E> {
protected static final int DEFAULT_CAPACITY = 10;
protected E [] data;
protected int size;
protected int modCount;
protected void ensureCapacity(int requiredCapacity) {
// etc.
}
protected class ArrayListIterator implements ListIterator<E> {
protected int cursor;
protected int priorCursor;
protected int expectedModCount;
protected void checkForComodification() {
// etc.
}
protected void updateAndSynchronizeModeCounts() {
// etc
}
}
Here is the program:
import java.util.Collection;
import java.util.List;
import java.util.Iterator;
import java.util.ListIterator;
/**
* Write a description of class W7Problem here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class W7Problem<E> extends ArrayList<E>
{
// Scaffolding for the problem. Don't touch.
public W7Problem() {
super();
}
// Scaffolding for the problem. Don't touch.
public W7Problem(int initialCapacity) {
super(initialCapacity);
}
/**
* Inserts all the elements of <tt>coll</tt> into this collection at
* the specified location. If both this collection and the parameter
* are the same collection, then the operational behavior is undefined
* (i.e. bad things can happen).
* #param index the location at which to insert
* #param coll the collection from which to draw elements for addition.
* #return true when this collection is modified as a result.
*
* Time complexity: TODO___________
*/
#Override
public boolean addAll(int index, Collection<? extends E> coll) {
// TODO: your code goes here
//throw new UnsupportedOperationException();
//checkBoundInclusive(index);
Iterator<? extends E> itr = coll.iterator();
int csize = coll.size();
modCount++;
if (csize + size > data.length){
ensureCapacity(size + csize);
}
int end = index + csize;
if (size > 0 && index != size){
System.arraycopy(data, index, data, end, size - index);
}
size += csize;
for ( ; index < end; index++){
data[index] = itr.next();
}
return csize > 0;
}
// Scaffolding for the problem. Don't touch.
#Override
public Iterator<E> iterator() {
return listIterator();
}
// Scaffolding for the problem. Don't touch.
#Override
public ListIterator<E> listIterator() {
return listIterator(0);
}
// Scaffolding for the problem. Don't touch.
#Override
public ListIterator<E> listIterator(int index) {
return new W7ProblemIterator(index);
}
private class W7ProblemIterator extends ArrayList<E>.ArrayListIterator {
// Scaffolding for the probmem. Don't touch.
public W7ProblemIterator(int startIndex) {
super(startIndex);
}
/**
* Replaces the last element returned by either <tt>next</tt> or
* <tt>previous</tt>. Cannot be called immediately after <tt>add</tt>
* or <tt>remove</tt>.
* #param obj the object with which to replace the one returned
* earlier.
*
* Time complexity: TODO___________
*/
#Override
public void set(E obj) {
// TODO: Your code goes here
//throw new UnsupportedOperationException();
//throw new UnsupportedOperationException("unsupported");
}
}
}
I have completed the addAll() method without any trouble and passed all of the test cases. My problem is with the set() method. No matter what I try, I cannot pass the last 3 test cases.
Is there any way to find the ListIterator.set() source code?
Any help is appreciated. I'm looking for a point in the right direction in how to write my set() method.
Thank you!
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++;
}
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)
Second programming class
So we have been tasked with a linked list, building each method from scratch.
Well I started on this day before yesterday and had a null pointer exception, I figured id iron it out later and continued.
Well after cutting my program down to nothing to find the culprit im left with code that SHOULD work as its copied from our lab (that worked).
If you guys think you can figure out why im getting a null pointer exception on my add method id greatly appreciate it and see if im doing the second constructor correctly. If I can get SOME traction on this to get started it would go allot easier but as is I cant even begin.
You will notice allot of blank methods, ill get to them once I can get my constructor + add method working
My code:
import java.util.Collection;
import java.util.Iterator;
/**
* Created by hhhh on 11/2/2014.
*/
public class Lset<R> implements Set151Interface<R> {
private Node head;
private int length;
/**In the first (following) constructor im trying to re use code and call my clear method.
*Should save space and make code look cleaner.
*/
public Lset(){
clear();
}
public Lset(Collection<? extends R> list){
this();
for (R object : list) {
add(object);
}
}
/**
* Copied from Lab7, this add method checks to see if there are more nodes than just the head.
* After the check if false, creates a new node and adds it to the end of the list.
* #param entry
* #return
*/
#Override
public boolean add(R entry) {
Node newNode = new Node(entry);
// empty list is handled differently from a non-empty list
if (head.next == null) {
head = newNode;
} else {
Node lastNode = getNodeAt(length - 1);
lastNode.next = newNode;
}
length++;
return true;
}
#Override
public void clear() {
this.length = 0;
this.head = null;
}
#Override
public boolean contains(Object o) {
return false;
}
#Override
public Iterator<R> iterator() {
return null;
}
#Override
public boolean containsAll(Collection<?> c) {
return false;
}
#Override
public boolean isEmpty() {
return false;
}
#Override
public boolean remove(Object o) {
return false;
}
#Override
public boolean addAll(Collection<? extends R> c) {
return false;
}
#Override
public boolean removeAll(Collection<?> c) {
return false;
}
#Override
public boolean retainAll(Collection<?> c) {
return false;
}
#Override
public int size() {
return length;
}
#Override
public Object[] toArray() {
return null;
}
#Override
public <T> T[] toArray(T[] array) {
return null;
}
/**
* Code used in Lab 7, getNodeAt uses the length field and starts at head to traverse array and arrive at the
* position desired.
* #param position
* #return
*/
private Node getNodeAt(int position) {
assert !isEmpty() && (position >= 0) && position < length;
Node cNode = head;
for (int i = 0; i < position; i++)
cNode = cNode.next;
assert cNode != null;
return cNode;
}
public String toString(){
String arrayString = "<";
for(int i = 0; i < length; i++){
String two = getNodeAt(i).toString();
arrayString += two;
if(i <= (length - 2)){
two = ", ";
arrayString += two;
}
}
arrayString += ">";
return arrayString;
}
//TODO comment better
public class Node {
/** Reference to the data */
public R data;
/** Reference to the next node is in the list */
public Node next;
/**
* Sets the data for this node.
* #param data data to be carried by this node.
*/
public Node(R data) {
this.data = data;
this.next = null;
}
/**
* Sets the data for the node and assigns the next node in the list.
* #param data data to be carried by this node.
* #param nextNode next node in the list.
*/
public Node(R data, Node nextNode) {
this.data = data;
this.next = nextNode;
}
/**
* Returns just the data portion of the node.
* #return The data portion of the node.
*/
public R getData() {
return this.data;
}
/**
* Modified just the data portion of the node.
* #param data new data to be contained within the node.
*/
public void setData(R data) {
this.data = data;
}
/**
* What node does this node point to.
* #return the node that this node points to or null if it does not
* point anywhere.
*/
public Node getNextNode() {
return this.next;
}
/**
* Change the node that this node points to.
* #param nextNode a new node for this node to point to.
*/
public void setNextNode(Node nextNode) {
this.next = nextNode;
}
/**
* Display the state of just the data portion of the node.
*/
public String toString() {
return this.data.toString();
}
}
}
This is the method in main thats killing it
private void testConstruction() {
System.out.println("\nTesting Constructor");
System.out.print("----------------------------------------");
System.out.println("----------------------------------------");
Set151Interface s = makeSet();
//added
s.add("Butterfinger");
test(s.size() == 0,
"size() should return 0: " + s.size());
test(s.toString().equals("<>"),
"toString returns \"<>\": " + s.toString());
ArrayList<String> temp = new ArrayList<String>();
temp.add("Butterfinger");
temp.add("Milky Way");
temp.add("Kit Kat");
temp.add("Three Muskateers");
Set151Interface s3 = makeSet(temp);
test(s3.size() == 4,
"size should return 4: " + s3.size());
test(s3.toString().equals("<Butterfinger, Milky Way, Kit Kat, Three Muskateers>"),
"toString should return\n "+
"\"<Butterfinger, Milky Way, Kit Kat, Three Muskateers>\":\n "
+ s3.toString());
}
as soon as butterfinger attempts to get added I get null pointer exception pointing to this line
if (head.next == null) {
You just declared private Node head; and it doesnt takes any value assigned . so the compiler throws NPE
Thanks for the help guys, I figured it out :).
On day one I had edited my driver (and forgot) once I re copied the driver everything works (so far) thanks again guys!
In a nutshell, I'm writing an application that needs a BlockingQueue implementation that provides both FIFO adds/removes, but also a fast contains method, as I'll be calling it a TON.
LinkedBlockingQueue gets me most of the way there, but it appears that its contains method runs in linear time, as it is based on AbstractQueue's contains method. I didn't see anything in the Java API that seemed to advertise an LBQ with fast contains out-of-the-box.
What makes things tougher is, my project is on a really severe time crunch (no, this isn't homework). I could do a quick-and-dirty LBQ extension with a HashSet underneath for fast contains, but I'm still going to have to test it, which could eat up a significant amount of man-hours. I'm wondering if there are any trusted/well-tested libraries out there that provide a LinkedBlockingQueue extension with a contains method that runs in O(1) time...? If not, any other suggestions are welcome.
Thanks again to all who provided input. I ended up coding my own HashedLinkedBlockingQueue implementation. Getting the synchronization correct by using the decorator pattern proved much more difficult than anticipated. Adding synchronization to the decorator caused deadlocks to occur under heavy load (particularly, put(E element) and take() introduced hold-and-wait conditions that previously didn't exist). When coupled with decreased performance because of unnecessary synchronization, it became apparent that I'd need to spend the time to get it right from scratch.
Performance in add/remove/contains is O(1) but comes with roughly double the synchronization cost of the original LinkedBlockingQueue - I say "roughly double" because the LBQ uses two locks - one for inserts and one for removes when the queue size is sufficiently large to allow concurrent modification of head and tail. My implementation uses a single lock, so removes must wait for adds to complete and vice versa. Here's the source code for the class - I have tested each method in both multi-threaded and single-threaded modes, but outside of using this class in my own application, I have not come up with a super-complicated, generalized test. Use at your own risk! Just because it works in my app doesn't mean there aren't still bugs:
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* Provides a single-lock queuing algorithm with fast contains(Object o) and
* remove(Object o), at the expense of higher synchronization cost when
* compared to {#link LinkedBlockingQueue}. This queue implementation does not
* allow for duplicate entries.
*
* <p>Use of this particular {#link BlockingQueue} implementation is encouraged
* when the cost of calling
* <code>{#link BlockingQueue#contains(Object o)}</code> or
* <code>{#link BlockingQueue#remove(Object o)}</code> outweighs the throughput
* benefit if using a {#link LinkedBlockingQueue}. This queue performs best
* when few threads require simultaneous access to it.
*
* <p>The basic operations this queue provides and their associated run times
* are as follows, where <i>n</i> is the number of elements in this queue and
* <i>m</i> is the number of elements in the specified collection, if any such
* collection is specified:
*
* <ul>
* <li><b>add(E element)</b> - <i>O(1)</i></li>
* <li><b>addAll(Collection<? extends E> c)</b> - <i>O(m)</i></li>
* <li><b>drainTo(Collection<? extends E> c, int maxElements)</b>
* - <i>O(maxElements*O(</i><code>c.add(Object o)</code><i>))</i></li>
* <li><b>contains(E element)</b> - <i>O(1)</i></li>
* <li><b>offer(E element)</b> - <i>O(1)</i></li>
* <li><b>poll()</b> - <i>O(1)</i></li>
* <li><b>remove(E element)</b> - <i>O(1)</i></li>
* <li><b>removeAll(Collection<? extends E> c)</b> - <i>O(m)</i></li>
* <li><b>retainAll(Collection<? extends E> c)</b> - <i>O(n*O(
* </i><code>c.contains(Object o)</code><i>))</i></li>
* </ul>
*
* #param <E> type of element this queue will handle. It is strongly
* recommended that the underlying element overrides <code>hashCode()</code>
* and <code>equals(Object o)</code> in an efficient manner.
*
* #author CodeBlind
*/
#SuppressWarnings("unused")
public class HashedLinkedBlockingQueue<E> implements BlockingQueue<E>{
/** Polling removes the head, offering adds to the tail. */
private Node head, tail;
/** Required for constant-time lookups and removals. */
private HashMap<E,Node> contents;
/** Allows the user to artificially limit the capacity of this queue. */
private final int maxCapacity;
//Constructors: -----------------------------------------------------------
/**
* Creates an empty queue with max capacity equal to
* {#link Integer#MAX_VALUE}.
*/
public HashedLinkedBlockingQueue(){ this(null,Integer.MAX_VALUE); }
/**
* Creates an empty queue with max capacity equals to the specified value.
* #param capacity (1 to {#link Integer#MAX_VALUE})
*/
public HashedLinkedBlockingQueue(int capacity){
this(null,Math.max(1,capacity));
}
/**
* Creates a new queue and initializes it to the contents of the specified
* collection, queued in the order returned by its iterator, with a max
* capacity of {#link Integer#MAX_VALUE}.
* #param c collection of elements to add
*/
public HashedLinkedBlockingQueue(Collection<? extends E> c){
this(c,Integer.MAX_VALUE);
}
/**
* Creates a new queue and initializes it to the contents of the specified
* collection, queued in the order returned by its iterator, with a max
* capacity equal to the specified value.
* #param c collection of elements to add
* #param capacity (1 to {#link Integer#MAX_VALUE})
*/
public HashedLinkedBlockingQueue(Collection<? extends E> c, int capacity){
maxCapacity = capacity;
contents = new HashMap<E,Node>();
if(c == null || c.isEmpty()){
head = null;
tail = null;
}
else for(E e : c) enqueue(e);
}
//Private helper methods: -------------------------------------------------
private E dequeue(){
if(contents.isEmpty()) return null;
Node n = head;
contents.remove(n.element);
if(contents.isEmpty()){
head = null;
tail = null;
}
else{
head.next.prev = null;
head = head.next;
n.next = null;
}
return n.element;
}
private void enqueue(E e){
if(contents.containsKey(e)) return;
Node n = new Node(e);
if(contents.isEmpty()){
head = n;
tail = n;
}
else{
tail.next = n;
n.prev = tail;
tail = n;
}
contents.put(e,n);
}
private void removeNode(Node n, boolean notify){
if(n == null) return;
if(n == head) dequeue();
else if(n == tail){
tail.prev.next = null;
tail = tail.prev;
n.prev = null;
}
else{
n.prev.next = n.next;
n.next.prev = n.prev;
n.prev = null;
n.next = null;
}
contents.remove(n.element);
if(notify) synchronized(this){ contents.notifyAll(); }
}
//Public instance methods: ------------------------------------------------
public void print(){
Node n = head;
int i = 1;
while(n != null){
System.out.println(i+": "+n);
n = n.next;
i++;
}
}
//Overridden methods: -----------------------------------------------------
#Override
public boolean add(E e){
synchronized(this){
if(remainingCapacity() < 1) throw new IllegalStateException();
enqueue(e);
contents.notifyAll();
}
return true;
}
#Override
public boolean addAll(Collection<? extends E> c){
boolean changed = true;
synchronized(this){
for(E e : c){
if(remainingCapacity() < 1) throw new IllegalStateException();
enqueue(e);
}
contents.notifyAll();
}
return changed;
}
#Override
public void clear(){
synchronized(this){
if(isEmpty()) return;
head = null;
tail = null;
contents.clear();
contents.notifyAll();
}
}
#Override
public boolean contains(Object o){
synchronized(this){ return contents.containsKey(o); }
}
#Override
public boolean containsAll(Collection<?> c) {
synchronized(this){
for(Object o : c) if(!contents.containsKey(o)) return false;
}
return true;
}
#Override
public int drainTo(Collection<? super E> c) {
return drainTo(c,maxCapacity);
}
#Override
public int drainTo(Collection<? super E> c, int maxElements) {
if(this == c) throw new IllegalArgumentException();
int transferred = 0;
synchronized(this){
while(!isEmpty() && transferred < maxElements)
if(c.add(dequeue())) transferred++;
if(transferred > 0) contents.notifyAll();
}
return transferred;
}
#Override
public E element(){
E e = peek();
if(e == null) throw new IllegalStateException();
return e;
}
#Override
public boolean isEmpty() {
synchronized(this){ return contents.isEmpty(); }
}
#Override
public Iterator<E> iterator(){ return new Itr(); }
#Override
public boolean offer(E e){
synchronized(this){
if(contents.containsKey(e)) return false;
enqueue(e);
contents.notifyAll();
}
return true;
}
#Override
public boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException{
long remainingSleep = -1;
long millis = unit.toMillis(timeout);
long methodCalled = System.currentTimeMillis();
synchronized(this){
while((remainingSleep =
(methodCalled+millis)-System.currentTimeMillis()) > 0 &&
(remainingCapacity() < 1 || contents.containsKey(e))){
contents.wait(remainingSleep);
}
if(remainingSleep < 1) return false;
enqueue(e);
contents.notifyAll();
}
return true;
}
#Override
public E peek(){
synchronized(this){ return (head != null) ? head.element : null; }
}
#Override
public E poll(){
synchronized(this){
E e = dequeue();
if(e != null) contents.notifyAll();
return e;
}
}
#Override
public E poll(long timeout, TimeUnit unit) throws InterruptedException{
E e = null;
long remainingSleep = -1;
long millis = unit.toMillis(timeout);
long methodCalled = System.currentTimeMillis();
synchronized(this){
e = dequeue();
while(e == null && (remainingSleep = (methodCalled+millis)-
System.currentTimeMillis()) > 0){
contents.wait(remainingSleep);
e = dequeue();
}
if(e == null) e = dequeue();
if(e != null) contents.notifyAll();
}
return e;
}
#Override
public void put(E e) throws InterruptedException{
synchronized(this){
while(remainingCapacity() < 1) contents.wait();
enqueue(e);
contents.notifyAll();
}
}
#Override
public int remainingCapacity(){ return maxCapacity-size(); }
#Override
public E remove(){
E e = poll();
if(e == null) throw new IllegalStateException();
return e;
}
#Override
public boolean remove(Object o){
synchronized(this){
Node n = contents.get(o);
if(n == null) return false;
removeNode(n,true);
}
return true;
}
#Override
public boolean removeAll(Collection<?> c){
if(this == c){
synchronized(this){
if(isEmpty()){
clear();
return true;
}
}
return false;
}
boolean changed = false;
synchronized(this){
for(Object o : c){
Node n = contents.get(o);
if(n == null) continue;
removeNode(n,false);
changed = true;
}
if(changed) contents.notifyAll();
}
return changed;
}
#Override
public boolean retainAll(Collection<?> c){
boolean changed = false;
if(this == c) return changed;
synchronized(this){
for(E e : new LinkedList<E>(contents.keySet())){
if(!c.contains(e)){
Node n = contents.get(e);
if(n != null){
removeNode(n,false);
changed = true;
}
}
}
if(changed) contents.notifyAll();
}
return changed;
}
#Override
public int size(){ synchronized(this){ return contents.size(); }}
#Override
public E take() throws InterruptedException{
synchronized(this){
while(contents.isEmpty()) contents.wait();
return dequeue();
}
}
#Override
public Object[] toArray(){
synchronized(this){ return toArray(new Object[size()]); }
}
#SuppressWarnings("unchecked")
#Override
public <T> T[] toArray(T[] a) {
synchronized(this){
//Estimate size of array; be prepared to see more or fewer elements
int size = size();
T[] r = a.length >= size ? a :
(T[])java.lang.reflect.Array
.newInstance(a.getClass().getComponentType(), size);
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) { // fewer elements than expected
if (a != r)
return Arrays.copyOf(r, i);
r[i] = null; // null-terminate
return r;
}
r[i] = (T)it.next();
}
return it.hasNext() ? finishToArray(r, it) : r;
}
}
//Static helper methods: --------------------------------------------------
#SuppressWarnings("unchecked")
private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
int i = r.length;
while (it.hasNext()) {
int cap = r.length;
if (i == cap) {
int newCap = ((cap / 2) + 1) * 3;
if (newCap <= cap) { // integer overflow
if (cap == Integer.MAX_VALUE)
throw new OutOfMemoryError
("Required array size too large");
newCap = Integer.MAX_VALUE;
}
r = Arrays.copyOf(r, newCap);
}
r[i++] = (T)it.next();
}
// trim if overallocated
return (i == r.length) ? r : Arrays.copyOf(r, i);
}
//Private inner classes: --------------------------------------------------
/**
* Provides a weak iterator that doesn't check for concurrent modification
* but also fails elegantly. A race condition exists when simultaneously
* iterating over the queue while the queue is being modified, but this is
* allowable per the Java specification for Iterators.
* #author CodeBlind
*/
private class Itr implements Iterator<E>{
private Node current;
private E currentElement;
private Itr(){
synchronized(HashedLinkedBlockingQueue.this){
current = head;
if(current != null) currentElement = current.element;
else currentElement = null;
}
}
#Override
public boolean hasNext(){
return currentElement != null;
}
#Override
public E next(){
if(currentElement == null) throw new NoSuchElementException();
synchronized(HashedLinkedBlockingQueue.this){
E e = currentElement;
current = current.next;
if(current == null || !contents.containsKey(current.element)){
current = null;
currentElement = null;
}
else currentElement = current.element;
return e;
}
}
#Override
public void remove(){
synchronized(HashedLinkedBlockingQueue.this){
if(current == null || !contents.containsKey(current.element))
throw new NoSuchElementException();
Node n = current;
current = current.next;
if(current != null && contents.containsKey(current.element))
currentElement = current.element;
else currentElement = null;
removeNode(n,true);
}
}
}
/**
* This class provides a simple implementation for a node in a double-
* linked list. It supports constant-time, in-place removals.
* #author CodeBlind
*/
private class Node{
private Node(E e){
element = e;
prev = null;
next = null;
}
private E element;
private Node prev, next;
#Override
public String toString(){
StringBuilder sb = new StringBuilder("Node[prev.element=");
if(prev == null) sb.append("null,element=");
else sb.append(prev.element+",element=");
sb.append(element+",next.element=");
if(next == null) sb.append("null]");
else sb.append(next.element+"]");
return sb.toString();
}
}
}
As others already said, using a hash-based structure is the solution.
I don't see any implementation on the Java Collection API.
But you can create a HashBlockingQueue decorator easily with the Guava class ForwardingBlockingQueue