I am working on zk tree by extending DefaultTreeModel. it's properly renders on webpage. But when I try to get the model associated with this tree using root, i am getting null.
I am using two ways to do that.
1. using Tree hierarchyTree; hierarchyTree.getModel().getRoot(); // returns null
2. using AdvancedTreeModel contactTreeModel extends DefaultTreeModel;
ContactTreeNode nodes2 = (ContactTreeNode) contactTreeModel.getRoot(); //also return null
Can you plz, tell me how can I get the root node, or model associate with it, which is not null. So that I can iterate over it.
AdvanceTeeModel.java
package demo.tree.dynamic_tree;
import org.zkoss.zul.DefaultTreeModel;
import org.zkoss.zul.DefaultTreeNode;
import demo.data.pojo.Contact;
public class AdvancedTreeModel extends DefaultTreeModel<Contact> {
private static final long serialVersionUID = -5513180500300189445L;
DefaultTreeNode<Contact> _root;
public AdvancedTreeModel(ContactTreeNode contactTreeNode) {
super(contactTreeNode);
_root = contactTreeNode;
}
/**
* remove the nodes which parent is <code>parent</code> with indexes
* <code>indexes</code>
*
* #param parent
* The parent of nodes are removed
* #param indexFrom
* the lower index of the change range
* #param indexTo
* the upper index of the change range
* #throws IndexOutOfBoundsException
* - indexFrom < 0 or indexTo > number of parent's children
*/
public void remove(DefaultTreeNode<Contact> parent, int indexFrom, int indexTo) throws IndexOutOfBoundsException {
DefaultTreeNode<Contact> stn = parent;
for (int i = indexTo; i >= indexFrom; i--)
try {
stn.getChildren().remove(i);
} catch (Exception exp) {
exp.printStackTrace();
}
}
public void remove(DefaultTreeNode<Contact> target) throws IndexOutOfBoundsException {
int index = 0;
DefaultTreeNode<Contact> parent = null;
// find the parent and index of target
parent = dfSearchParent(_root, target);
if(parent!=null){
for (index = 0; index < parent.getChildCount(); index++) {
if (parent.getChildAt(index).equals(target)) {
break;
}
}
remove(parent, index, index);
}
}
/**
* insert new nodes which parent is <code>parent</code> with indexes
* <code>indexes</code> by new nodes <code>newNodes</code>
*
* #param parent
* The parent of nodes are inserted
* #param indexFrom
* the lower index of the change range
* #param indexTo
* the upper index of the change range
* #param newNodes
* New nodes which are inserted
* #throws IndexOutOfBoundsException
* - indexFrom < 0 or indexTo > number of parent's children
*/
public void insert(DefaultTreeNode<Contact> parent, int indexFrom, int indexTo, DefaultTreeNode<Contact>[] newNodes)
throws IndexOutOfBoundsException {
DefaultTreeNode<Contact> stn = parent;
for (int i = indexFrom; i <= indexTo; i++) {
try {
stn.getChildren().add(i, newNodes[i - indexFrom]);
} catch (Exception exp) {
throw new IndexOutOfBoundsException("Out of bound: " + i + " while size=" + stn.getChildren().size());
}
}
}
/**
* append new nodes which parent is <code>parent</code> by new nodes
* <code>newNodes</code>
*
* #param parent
* The parent of nodes are appended
* #param newNodes
* New nodes which are appended
*/
public void add(DefaultTreeNode<Contact> parent, DefaultTreeNode<Contact>[] newNodes) {
DefaultTreeNode<Contact> stn = (DefaultTreeNode<Contact>) parent;
for (int i = 0; i < newNodes.length; i++)
stn.getChildren().add(newNodes[i]);
}
private DefaultTreeNode<Contact> dfSearchParent(DefaultTreeNode<Contact> node, DefaultTreeNode<Contact> target) {
if (node.getChildren() != null && node.getChildren().contains(target)) {
return node;
} else {
int size = getChildCount(node);
for (int i = 0; i < size; i++) {
DefaultTreeNode<Contact> parent = dfSearchParent((DefaultTreeNode<Contact>) getChild(node, i), target);
if (parent != null) {
return parent;
}
}
}
return null;
}
}
Actually I am using this example,
[http://www.zkoss.org/zkdemo/tree/dynamic_tree][Dynamic Tree from ZK]
And in Composer's override render method i am using following line of code to get the root/model from the tree.
ContactTreeNode nodes = (ContactTreeNode) hierarchyTree.getModel().getRoot();
System.out.println("nodes: " + nodes);
ContactTreeNode nodes2 = (ContactTreeNode) contactTreeModel.getRoot();
Your remove method have to care about removing the root.
Means, if you remove the root, you have to set a new one.
Try if is solves the problem. Or try if the problem occurs
right after initialization of (and without editing) the tree.
Related
I am trying to write the following method for a lab assignment but have become very stuck on it. We are working with binary search tree's and they have asked for this method "int sizeBelow(T high) returns the number of elements in the tree that are strictly less than high" If someone could help me figure out how to write this it would be really appreciated! Been stuck on this for way too long
package week11;
import java.util.Scanner;
import static week11.LinkedBST.Direction.*;
/**
* A binary tree implementation using links. We assume that the tree
* is not to store 'null' elements. In particular if the root node
* *is* null then the tree is empty. This can only occur if a tree
* is initially constructed with no arguments, or if we remove the
* only element from a tree.
*
* #author Michael Albert, Iain Hewson
*/
public class LinkedBST<T extends Comparable<T>> {
/** The element held at the root of this tree. */
private T root;
/** The left subtree of this tree. */
private LinkedBST<T> left;
/** The right subtree of this tree. */
private LinkedBST<T> right;
/**
* Creates a BST with the given value.
*
* #param value to store at the root of this LinkedBST.
*/
public LinkedBST(T value) {
root = value;
left = null;
right = null;
}
/**
* Creates a new empty BST.
*/
public LinkedBST() {
this(null);
}
/**
* Adds an element to this BST if it isn't already there.
*
* #param element an element to be added.
*/
public void add(T element) {
if (root == null) {
root = element;
}
int comparison = root.compareTo(element);
if (comparison > 0) {
if (left == null) {
left = new LinkedBST<T>(element);
} else {
left.add(element);
}
} else if (comparison < 0) {
if (right == null) {
right = new LinkedBST<T>(element);
} else {
right.add(element);
}
}
}
/**
* Returns the height of this tree.
*
* #return the height of this tree.
*/
public int height() {
int leftH = 0, rightH = 0;
if (root == null) {
return 0;
}
if (right != null) {
rightH = 1 + right.height();
}
if (left != null) {
leftH = 1 + left.height();
}
return Math.max(leftH, rightH);
}
/**
* Searches for the given target within this tree.
*
* #param target
* #return true if target is found, otherwise false.
*/
public boolean search(T target) {
boolean lefth = false, righth = false;
if (root == null) {
return false;
}
int comparison = root.compareTo(target);
if (comparison == 0) {
return true;
}
if (comparison > 0) {
if (left != null) {
lefth = left.search(target);
}
return lefth;
}
if (comparison < 0) {
if (right != null) {
righth = right.search(target);
}
return righth;
}
return false;
}
/**
* Returns the size of this BST.
*
* #return the size of this BST.
*/
public int size() {
int lefth = 0, righth = 0;
if (root == null) {
return 0;
}
if (right != null) {
righth = right.size();
}
if (left != null) {
lefth = left.size();
}
return 1 + lefth + righth;
}
/**
* Returns how many elements are greater than or equal to the
* parameter <code>low</code>.
*
* #param low the lower bound to use when counting elements.
* #return how many elements are greater than or equal to the
* parameter <code>low</code>.
*/
public int sizeAbove(T low) {
if (root == null) {
return 0;
}
return 0;
}
/**
* Returns how many elements are less than the parameter
* <code>high</code>.
*
* #param high the element to compare when counting elements.
* #return how many elements are less than the parameter
* <code>high</code>.
*/
public int sizeBelow(T high) {
// implement this for part 2
return 0;
}
/**
* Returns how many elements are greater than or equal to the
* parameter <code>low</code> and less than the parameter
* <code>high</code>.
*
* #param low the lower bound to use when counting elements.
* #param high the upper bound to use when counting elements.
* #return how many elements are between low (inclusive) and
* high (exclusive).
*/
public int sizeBetween(T low, T high) {
// implement this for part 2
return 0;
}
/**
* Removes the given element from this tree if it is present.
*
* #param element the element to remove.
*/
public void remove(T element) {
// implement this method from the lectures if you
// want to do the extension exercises
}
/** The direction used when creating a representation of this tree. */
enum Direction {LEFT, RIGHT, NO};
/**
* Recursively generates a representation of this tree.
*
* #param curr the current line being generated.
* #param dir the direction of the last link followed.
* #param result the representation generated so far.
* #return a representation of this tree.
*/
public StringBuilder str(String curr, Direction dir, StringBuilder result) {
if(right != null) {
right.str(curr + (dir == LEFT ? "│ " : " "), RIGHT, result);
}
if (root != null) {
result.append(curr + (dir == RIGHT ? "┌─ " :
dir == LEFT ? "└─ " : " ") + root + "\n");
}
if(left != null) {
left.str(curr + (dir == RIGHT ? "│ " : " "), LEFT, result);
}
return result;
}
#Override
public String toString() {
return str("", NO, new StringBuilder()).toString();
}
/**
* Entry point of program (used for testing).
* Valid commands are:
* <pre>
* a (add) item(s) - calls add with each item
* f (find) item - calls search with item
* p (print) - calls toString
* h (height) - calls height
* s (size) - calls size
* sa (sizeabove) low - calls sizeAbove(low)
* sb (sizebelow) high - calls sizeBelow(high)
* si (sizeinbetween) low high - calls sizeBetween(low,high)
* </pre>
* Return values of methods are printed to stdout.
*
* #param args command line arguments are not used.
*/
public static void main(String[] args) {
LinkedBST<String> tree = new LinkedBST<>();
Scanner input = new Scanner(System.in);
while (input.hasNextLine()) {
Scanner line = new Scanner(input.nextLine());
if (line.hasNext()) {
String command = line.next();
switch (command) {
case "a": case "add":
while (line.hasNext()) {
tree.add(line.next());
}
break;
case "f": case "find":
if (line.hasNext()) {
System.out.println(tree.search(line.next()));
}
break;
case "p": case "print":
System.out.print(tree);
break;
case "h": case "height":
System.out.println(tree.height());
break;
case "s": case "size":
System.out.println(tree.size());
break;
case "sa": case "sizeabove":
if (line.hasNext()) {
String low = line.next();
System.out.println(tree.sizeAbove(low));
}
break;
case "sb": case "sizebelow":
if (line.hasNext()) {
package week11;
import java.util.Scanner;
import static week11.LinkedBST.Direction.*;
/**
* A binary tree implementation using links. We assume that the tree
* is not to store 'null' elements. In particular if the root node
* *is* null then the tree is empty. This can only occur if a tree
* is initially constructed with no arguments, or if we remove the
* only element from a tree.
*
* #author Michael Albert, Iain Hewson
*/
public class LinkedBST<T extends Comparable<T>> {
/** The element held at the root of this tree. */
private T root;
/** The left subtree of this tree. */
private LinkedBST<T> left;
/** The right subtree of this tree. */
private LinkedBST<T> right;
/**
* Creates a BST with the given value.
*
* #param value to store at the root of this LinkedBST.
*/
public LinkedBST(T value) {
root = value;
left = null;
right = null;
}
/**
* Creates a new empty BST.
*/
public LinkedBST() {
this(null);
}
/**
* Adds an element to this BST if it isn't already there.
*
* #param element an element to be added.
*/
public void add(T element) {
if (root == null) {
root = element;
}
int comparison = root.compareTo(element);
if (comparison > 0) {
if (left == null) {
left = new LinkedBST<T>(element);
} else {
left.add(element);
}
} else if (comparison < 0) {
if (right == null) {
right = new LinkedBST<T>(element);
} else {
right.add(element);
}
}
}
/**
* Returns the height of this tree.
*
* #return the height of this tree.
*/
public int height() {
int leftH = 0, rightH = 0;
if (root == null) {
return 0;
}
if (right != null) {
rightH = 1 + right.height();
}
if (left != null) {
leftH = 1 + left.height();
}
return Math.max(leftH, rightH);
}
/**
* Searches for the given target within this tree.
*
* #param target
* #return true if target is found, otherwise false.
*/
public boolean search(T target) {
boolean lefth = false, righth = false;
if (root == null) {
return false;
}
int comparison = root.compareTo(target);
if (comparison == 0) {
return true;
}
if (comparison > 0) {
if (left != null) {
lefth = left.search(target);
}
return lefth;
}
if (comparison < 0) {
if (right != null) {
righth = right.search(target);
}
return righth;
}
return false;
}
/**
* Returns the size of this BST.
*
* #return the size of this BST.
*/
public int size() {
int lefth = 0, righth = 0;
if (root == null) {
return 0;
}
if (right != null) {
righth = right.size();
}
if (left != null) {
lefth = left.size();
}
return 1 + lefth + righth;
}
/**
* Returns how many elements are greater than or equal to the
* parameter <code>low</code>.
*
* #param low the lower bound to use when counting elements.
* #return how many elements are greater than or equal to the
* parameter <code>low</code>.
*/
public int sizeAbove(T low) {
if (root == null) {
return 0;
}
return 0;
}
/**
* Returns how many elements are less than the parameter
* <code>high</code>.
*
* #param high the element to compare when counting elements.
* #return how many elements are less than the parameter
* <code>high</code>.
*/
public int sizeBelow(T high) {
// implement this for part 2
return 0;
}
/**
* Returns how many elements are greater than or equal to the
* parameter <code>low</code> and less than the parameter
* <code>high</code>.
*
* #param low the lower bound to use when counting elements.
* #param high the upper bound to use when counting elements.
* #return how many elements are between low (inclusive) and
* high (exclusive).
*/
public int sizeBetween(T low, T high) {
// implement this for part 2
return 0;
}
/**
* Removes the given element from this tree if it is present.
*
* #param element the element to remove.
*/
public void remove(T element) {
// implement this method from the lectures if you
// want to do the extension exercises
}
/** The direction used when creating a representation of this tree. */
enum Direction {LEFT, RIGHT, NO};
/**
* Recursively generates a representation of this tree.
*
* #param curr the current line being generated.
* #param dir the direction of the last link followed.
* #param result the representation generated so far.
* #return a representation of this tree.
*/
public StringBuilder str(String curr, Direction dir, StringBuilder result) {
if(right != null) {
right.str(curr + (dir == LEFT ? "│ " : " "), RIGHT, result);
}
if (root != null) {
result.append(curr + (dir == RIGHT ? "┌─ " :
dir == LEFT ? "└─ " : " ") + root + "\n");
}
if(left != null) {
left.str(curr + (dir == RIGHT ? "│ " : " "), LEFT, result);
}
return result;
}
#Override
public String toString() {
return str("", NO, new StringBuilder()).toString();
}
/**
* Entry point of program (used for testing).
* Valid commands are:
* <pre>
* a (add) item(s) - calls add with each item
* f (find) item - calls search with item
* p (print) - calls toString
* h (height) - calls height
* s (size) - calls size
* sa (sizeabove) low - calls sizeAbove(low)
* sb (sizebelow) high - calls sizeBelow(high)
* si (sizeinbetween) low high - calls sizeBetween(low,high)
* </pre>
* Return values of methods are printed to stdout.
*
* #param args command line arguments are not used.
*/
public static void main(String[] args) {
LinkedBST<String> tree = new LinkedBST<>();
Scanner input = new Scanner(System.in);
while (input.hasNextLine()) {
Scanner line = new Scanner(input.nextLine());
if (line.hasNext()) {
String command = line.next();
switch (command) {
case "a": case "add":
while (line.hasNext()) {
tree.add(line.next());
}
break;
case "f": case "find":
if (line.hasNext()) {
System.out.println(tree.search(line.next()));
}
break;
case "p": case "print":
System.out.print(tree);
break;
case "h": case "height":
System.out.println(tree.height());
break;
case "s": case "size":
System.out.println(tree.size());
break;
case "sa": case "sizeabove":
if (line.hasNext()) {
String low = line.next();
System.out.println(tree.sizeAbove(low));
}
break;
case "sb": case "sizebelow":
if (line.hasNext()) {
System.out.println(tree.sizeBelow(line.next()));
}
break;
case "si": case "sizeinbetween":
if (line.hasNext()) {
String low = line.next();
if (line.hasNext()) {
System.out.println(tree.sizeBetween
(low, line.next()));
}
}
break;
default:
System.err.println("Unknown command: " + command);
}
}
}
}
}
System.out.println(tree.sizeBelow(line.next()));
}
break;
case "si": case "sizeinbetween":
if (line.hasNext()) {
String low = line.next();
if (line.hasNext()) {
System.out.println(tree.sizeBetween
(low, line.next()));
}
}
break;
default:
System.err.println("Unknown command: " + command);
}
}
}
}
}
As this is homework I will try to point you in the right direction rather than do it for you. The task at hand is better solved with recursion and when it comes to binary trees, there are several different types of traversals that can be done recursively.
In-order traversal (LVR)
Reverse order traversal (RVL)
Preorder traversal (VLR)
Postorder traversal (LRV)
I would perform an In-order traversal and increment accordingly if we find any value below high.
Hint:
you'll need to create an inOrder method which takes an argument of the root and an argument of T high and recursively traverse down the tree checking if the current node value is less that high.
public int sizeBelow(T high) {
// return inOrder(root,high);
}
private int inOrder(type current, type high){
// check if ANY of root or high are null (if yes return 0)
// recursively go down the tree comparing current against high
// if current is less than high then return 1 + inOrder(...,high)
// all other conditions should return 0.
}
Ensure you read on Tree Traversals (Inorder, Preorder and Postorder). When you click on this link ensure you select the JAVA tab because by default the examples are shown in C.
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;
}
}
}
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!
I have spent entire weekend playing around with this. I am trying to store the nodes in PriorityQueue data structure. My astar function doesnt seem to be doing what it should. Anyone mind having a look?
public void aStar(Node from, Node to) {
PriorityQueue<Node> exploreList = new PriorityQueue<Node>();
ArrayList<Node> visited = new ArrayList<Node>();
ArrayList<Node> successors = new ArrayList<Node>();
Node current = from;
System.out.println(current.getName());
while (current != to) {
successors = current.getConnected();
Collections.sort(successors);
for (Node n : successors) {
if (!visited.contains(n)) {
exploreList.add(n);
}
for (Node n1 : successors) {
if (n.fSum() > n1.fSum()) {
exploreList.remove(n);
exploreList.add(n1);
}
}
}
visited.add(current);
current = exploreList.remove();
System.out.println(current.getName());
}
Node Class here
public class Node implements Comparable {
private String name;
private int travDist;
private int straightDist;
private ArrayList<Arc> arcs;
/**
* Constructor for a new node
*
* #param n
*/
public Node(String n, int aTravDist, int aStraightDist) {
name = n;
travDist = aTravDist;
straightDist = aStraightDist;
arcs = new ArrayList<Arc>();
}
/**
* Adds a new arc
*
* #param to
* #param c
*/
public void addArc(Node to, int c) {
arcs.add(new Arc(to, c));
}
/**
* Gets the list of connected nodes to this node
*
* #return
*/
public ArrayList<Node> getConnected() {
ArrayList<Node> returnData = new ArrayList<Node>();
for (Arc a : arcs) {
returnData.add(a.getNode());
}
return returnData;
}
#Override
public int compareTo(Object o) {
//return name.compareTo(((Node) o).getName());
Integer sum = ((Node)o).fSum();
return sum.compareTo(fSum());
}
public int fSum () {
return travDist + straightDist;
}
/**
* Gets the name of the Node
*
* #return
*/
public String getName() {
return name;
}
}
What you are doing is not a proper A star algorithm.
Collections.sort(successors);
You shouldn't do that. In A star you always consider all the successors. You needn't worry about the order- the priority queue will take care of that. However, adding this line increases the complexity of the algorithm.
for (Node n1 : successors) {
if (n.fSum() > n1.fSum()) {
exploreList.remove(n);
exploreList.add(n1);
}
}
This is entirely wrong. What you are doing here is: you only add the closest of all the successors. This will be a beam search with a beam of size 1, not A star - just keep them all in.