Why won't my ArrayList initialize properly? - java

I am having frustrating trouble getting my ArrayList to initialize. I am getting an error at the line binaryTreeList.set(1, root); saying
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.set(Unknown Source)
at BinaryTreeADT.<init>(BinaryTreeADT.java:18)
at Driver.main(Driver.java:7)
I'm trying to implement a simple binary tree using an ArrayList and I'd like the "root" element to be at ArrayList position 1. For some reason, the size of the `binaryTreeList is not growing, despite adding nodes to all of them.
Here is my code in order of Driver, BinaryTreeADT and MyTreeNode
public class Driver {
public static void main(String[] args) {
MyTreeNode mtn = new MyTreeNode(3, 'R');
BinaryTreeADT bt = new BinaryTreeADT(mtn);
bt.printTree();
}
}
BinaryTreeADT:
import java.util.ArrayList;
import javax.swing.tree.TreeNode;
public class BinaryTreeADT {
private ArrayList<MyTreeNode> binaryTreeList;
private MyTreeNode nullNode = new MyTreeNode(true); //This creates a null node that initially populates the array.
//Constructor with no root
public BinaryTreeADT(){
binaryTreeList = new ArrayList<MyTreeNode>(10);
}
public BinaryTreeADT(MyTreeNode root){
binaryTreeList = new ArrayList<MyTreeNode>(10);
initializeList();
binaryTreeList.set(1, root);
}
private void initializeList(){
for (int i = 0; i < binaryTreeList.size(); i++){
binaryTreeList.add(nullNode);
}
}
public void add(){
}
public void printTree(){
for (int i = 0; i < binaryTreeList.size(); i++){
if (binaryTreeList.get(i) != null)
System.out.println(binaryTreeList.get(i).getNodeChar() + " | ");
}
}
}
MyTreeNode:
import java.util.Enumeration;
import javax.swing.tree.TreeNode;
public class MyTreeNode implements TreeNode {
private int nodeKey;
private char nodeChar;
private boolean isNull;
public MyTreeNode(int key, char letter){
nodeKey = key;
nodeChar = letter;
}
//Constructor for Null Node
public MyTreeNode(boolean setNull){
isNull = setNull;
}
public boolean isNull(){ //Tells if this is a null node
return isNull;
}
#Override
public Enumeration children() {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean getAllowsChildren() {
// TODO Auto-generated method stub
return false;
}
#Override
public TreeNode getChildAt(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int getChildCount() {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getIndex(TreeNode arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public TreeNode getParent() {
// TODO Auto-generated method stub
return null;
}
public int getNodeKey() {
return nodeKey;
}
public void setNodeKey(int nodeKey) {
this.nodeKey = nodeKey;
}
public char getNodeChar() {
return nodeChar;
}
public void setNodeChar(char nodeChar) {
this.nodeChar = nodeChar;
}
#Override
public boolean isLeaf() {
// TODO Auto-generated method stub
return false;
}
}

Reason is this line:
binaryTreeList.set(1, root);
Because size of binaryTreeList is zero . You have constructed the ArrayList and told it to have the initial Capacity to be 10 using constructor ArrayList(int initialCapacity) , But since nothing is inside ArrayList right now , so ArrayList#size() is returning as 0. That's why within your initializeList method the for loop is exited at very first iteration which is not initializing the binaryTreeList with 10 elements. So the size of binaryTreeList is again still 0. This is the reason that setting a value at index 1 which is not existing at all is throwing IndexOutOfBoundException.
You should instead define initializeList as:
private void initializeList(){
for (int i = 0; i < 10; i++){
binaryTreeList.add(nullNode);
}
}

You are attempting to set the element at position 1 when your ArrayList is empty:
binaryTreeList.set(1, root);
Instead just use:
binaryTreeList.add(root);

Your reference is out of bounds. You should set the 0th index to your root node. However, since your ArrayList is empty (size = 0), you need to actually add the new element, which will increment the size of the array.
binaryTreeList.add(root);
With arrays, indices start at 0, so the element at index 0 of an array is the first element, the element at index 1 is the second, etc. If you have an array of size n, the last element will be at index n-1.
Later, if you want to change an element at a certain index, you can set the 0th element to root:
binaryTreeList.set(0, root);
This will work provided the first argument (0 in this case) is less than or equal to the binaryTreeList.size()-1.

Related

Binary Search Tree Instantiaition

I have Created Binary Search Tree by Using a Tree Interface and Recursion (I am aware that using a Node Class I can Implement the same ) providing methods for Adding and Checking if an element is in the Binary Search Tree or not.
The Problem I am facing is in instantiating & displaying the elements of the BST.
Here is my code
Tree Interface:
package bst;
public interface Tree<D extends Comparable>{
public boolean isempty();
public int cardinality();
public boolean member(D elt);
public NonEmptyBst<D> add(D elt);
}
EmptyBst Class:
package bst;
public class EmptyBst<D extends Comparable> implements Tree<D>{
public EmptyBst(){
D data=null;
}
#Override
public boolean isempty() {
// TODO Auto-generated method stub
return true;
}
#Override
public int cardinality() {
// TODO Auto-generated method stub
return 0;
}
#Override
public boolean member(D elt) {
// TODO Auto-generated method stub
return false;
}
#Override
public NonEmptyBst<D>add(D elt) {
// TODO Auto-generated method stub
return new NonEmptyBst<D>(elt);
}
}
NonEmptyBst Class
package bst;
public class NonEmptyBst<D extends Comparable> implements Tree<D> {
D data;
D root;
Tree<D> left;
Tree <D>right;
public NonEmptyBst(D elt){
data=elt;
root=elt;
left=new EmptyBst<D>();
right=new EmptyBst<D>();
}
NonEmptyBst(){
D dataThis=this.data;
}
public NonEmptyBst(D elt,Tree<D>leftTree,Tree<D>rightTree){
data=elt;
left=leftTree;
right=rightTree;
}
#Override
public boolean isempty() {
// TODO Auto-generated method stub
return false;
}
#Override
public int cardinality() {
// TODO Auto-generated method stub
return 1+left.cardinality()+right.cardinality();
}
public boolean member(D elt) {
if (data == elt) {
return true;
} else {
if (elt.compareTo(data) < 0) {
return left.member(elt);
} else {
return right.member(elt);
}
}
}
public NonEmptyBst<D> add(D elt) {
if (data == elt) {
return this;
} else {
if (elt.compareTo(data) < 0) {
return new NonEmptyBst(data, left.add(elt), right);
} else {
return new NonEmptyBst(data, left, right.add(elt));
}
}
}
}
BinarySearchTree Class
package bst;
import bst.Tree;
import bst.EmptyBst;
import bst.NonEmptyBst;
public class BinarySearchTree {
public static void main(String[] args) {
// TODO Auto-generated method stub
NonEmptyBst abcd=new NonEmptyBst( "abc");
NonEmptyBst ab=new NonEmptyBst(67);
abcd.add("cry me a river");
abcd.add("geeehfvmfvf");
abcd.add("I'm Sexy and i know it");
abcd.add("zzzzsd");
abcd.add("zzzzsd");
abcd.add("zzzfdsf");
abcd.add("zzfedfrsd");
abcd.add("tgrgdzsd");
abcd.add("gtrgrtgtrgtrzzzzsd");
abcd.add("zzzzsd");
abcd.add("zdddzzzsd");
abcd.add("zzzzsd");
abcd.add("zzzzsd");
}
}
**
How Can I access the data at all nodes and then Print Them out?The Particular Problem I am facing is In Getting an exception namely ClassCastException when I access the "leaf Nodes" and even if I Initalize new NonEmptyBst<D>in My NonEmptyBst<D>(D elt) constructor I end Up having a null pointer Exception
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.compareTo(Unknown Source)
at java.lang.String.compareTo(Unknown Source)
at bst.NonEmptyBst.add(NonEmptyBst.java:51)
at bst.NonEmptyBst.add(NonEmptyBst.java:54)
at bst.BinarySearchTree.main(BinarySearchTree.java:11)
I'm not really sure I see the need for EmptyBst unless you are trying to follow the design-pattern for a Null Object.
Specifically, an "empty" tree can easily be checked if data == null && left == null && right == null. Also, no need for data here, since it is a local variable and never referenced.
public EmptyBst(){
D data=null;
}
And is there a difference between D data and D root?
I think you need to adjust your add method to capture the result of the recursion.
public NonEmptyBst<D> add(D elt) {
if (data == elt) {
return this;
} else {
if (elt.compareTo(data) < 0) {
this.left = this.left.add(elt);
} else {
this.right = this.right.add(elt);
}
}
return this;
}
You need to access it recursively. As I don't have your node implementation I'll write a general example:
// Return a list with all the nodes
public List<Node> preOrder() {
List<Node> l = new ArrayList<Node>();
l.add(this.value); // Add the data of the root
if(this.left != null) // Add elements to the left
l.addAll(this.left.preOrder());
if(this.right != null) // Add elements to the right
l.addAll(this.right.preOrder());
return l;
}
Then you would simply call it:
List<Node> nodes = myTree.preOrder();
And then loop through the list to do whatever you want.

Create a recently used list in java

I have a task where i have to create a recently used list in java. I'm a bit lost and I do not really know where to start. Please help! This is the code I have been given to start with:
public class RecentlyUsedList {
// Members (a.k.a. fields)
private String[] theItems;
private int noOfItems;
// Constructor
public RecentlyUsedList(int capacity) {
// Create the array with indicated capacity
// Initialize numberOfItems
}
// Public methods
public int getNoOfItems() {
}
public boolean isEmpty() {
// Is this list empty or not?
}
public String getItemAt(int index) {
// If index is out of range, return null
// Otherwise return a reference to the indicated item
}
public void addItem(String item) {
// 1. Check if the list contains this item; if so, remove it and pack
// 2. Check if the array needs resizing
// 3. Add the item to the list. Increment noOfItems.
}
public void removeItem(String item) {
// Check if the list contains this item; if so, remove it and call pack
// NB! use equals to compare Strings, e.g. str1.equals(str2)
}
public String toString() {
// Return a string of the form
// [1st item; 2nd item; ...]
}
// Private (helper) methods
private void pack(int index) {
// In a loop, starting at "index", copy item at position+1 to position
// (if the items are stored in "reverse order")
// Decrement noOfItems.
}
private void resize() {
// Create a new, temporary, reference and a corresponding String-array
// Copy all item-references to the new array
// Let the "theList" reference the new array (i.e. theItems = temp)
}
}
Please does anyone have directions on how to start?
Giving you a head start by giving code for 3 methods. Rest you can attempt on your own.
// Public methods
public int getNoOfItems() {
return noOfItems;
}
public String getItemAt(int index) {
if (index >= noOfItems) {
return null;
} else {
return theItems[index];
}
}
public String toString() {
StringBuilder builder = new StringBuilder("[");
for (int i = 0; i < theItems.length; i++) {
if (theItems[i] != null) {
builder.append(theItems[i]).append(";");
}
builder.append("]");
return builder.toString();
}

Having trouble with my CircularList

Right now I am trying to create a circular list, where when I use hasNext() from an Iterator it should always return true. However right now it is returning that it is not a circular list, and I am also having problems printing out the values (in this example Strings) of the ArrayList. Here is the CircularList class I created, which has a inner Node class for the objects that are put into the list:
public class CircularList<E> implements Iterable{
private Node<E> first = null;
private Node<E> last = null;
private Node<E> temp;
private int size = 0;
//inner node class
private static class Node<E>{ //In this case I am using String nodes
private E data; //matching the example in the book, this is the data of the node
private Node<E> next = null; //next value
//Node constructors, also since in this case this is a circular linked list there should be no null values for previous and next
private Node(E data){
this.data = data;
}
}
//end of inner node class
public void addValue(E item){
Node<E> n = new Node<E>(item);
if(emptyList() == true){ //if the list is empty
//only one value in the list
first = n;
last = n;
}
else{ //if the list has at least one value already
//store the old first value
temp = first;
//the new first is the input value
first = n;
//next value after first is the old first value
first.next = temp;
//if after this there will be only two values in the list once it is done
if(size == 1){
last = temp;
}
//if the list is greater than one than the last value does not change, since any other values will be put before last in this case, and not replace it
//creating the circular part of the list
last.next = first;
}
size++;
}
public boolean emptyList(){
boolean result = false;
if(first == null && last == null){ //if there is no values at all
result = true;
}
return result;
}
#Override
public Iterator<E> iterator() {
// TODO Auto-generated method stub
return new CircularIterator<E>(); //each time this method is called it will be creating a new instance of my Iterator
}
}
Here is the Iterator class I am making:
public class CircularIterator<E> implements Iterator<E> {
#Override
public boolean hasNext() {
return false;
}
#Override
public E next() {
// TODO Auto-generated method stub
return null;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
}
and finally the Test class:
public class Test {
static CircularList<String> c = new CircularList<String>(); //in this case it is a string list
static Iterator it = c.iterator();
public static void main(String[]args){
c.addValue("Bob");
c.addValue("Joe");
c.addValue("Jaina");
c.addValue("Hannah");
c.addValue("Kelly");
Iterate();
for(String val : c){
System.out.println(val);
}
}
private static boolean Iterate(){
boolean result = false;
if(!it.hasNext()){
System.out.println("Not a circular list!");
}
else{
result = true;
}
return result;
}
}
Again I am trying to get it to always return true, I think the problem lies with my hasNext() method, but I am not completely sure.
The main problem with your approach is you are using static inner classes - this is not necessary. Making the outer class generic is sufficient. The generic parameter is then inherited by the inner classes and all sorts of issues disappear.
Implementing an Iterator properly is subtle.
public static class CircularList<E> implements Iterable<E> {
private Node first = null;
private Node last = null;
private int size = 0;
private class Node {
private E data;
private Node next = null;
private Node(E data) {
this.data = data;
}
}
public void addValue(E item) {
Node n = new Node(item);
if (emptyList()) {
//only one value in the list
first = n;
last = n;
} else { //if the list has at least one value already
//store the old first value
Node temp = first;
//the new first is the input value
first = n;
//next value after first is the old first value
first.next = temp;
//if after this there will be only two values in the list once it is done
if (size == 1) {
last = temp;
}
//if the list is greater than one than the last value does not change, since any other values will be put before last in this case, and not replace it
//creating the circular part of the list
last.next = first;
}
size++;
}
public boolean emptyList() {
boolean result = false;
if (first == null && last == null) { //if there is no values at all
result = true;
}
return result;
}
#Override
public Iterator<E> iterator() {
return new CircularIterator(); //each time this method is called it will be creating a new instance of my Iterator
}
private class CircularIterator implements Iterator<E> {
// Start at first.
Node next = first;
public CircularIterator() {
}
#Override
public boolean hasNext() {
// Stop when back to first.
return next != null;
}
#Override
public E next() {
if (hasNext()) {
E n = next.data;
next = next.next;
if (next == first) {
// We're done.
next = null;
}
return n;
} else {
throw new NoSuchElementException("next called after end of iteration.");
}
}
}
}
public void test() {
CircularList<String> c = new CircularList<>();
c.addValue("A");
c.addValue("B");
c.addValue("C");
c.addValue("D");
for (String s : c) {
System.out.println(s);
}
}
Your main code was essentially correct - all I did was remove the unnecessary generics parameters from the inner classes.
Note that the way you add node to the list means that the items come out backwards. You could adjust that in your addValue method quite easily.
You can simply use following for circular iteration. This Circular list behave as same as other java.util.Lists. But it's iteration is modified. You don't need to care about it's performance tuning additionally. Because it's super class (LinkedList) is already well tested and enough stronger to use.
`public class CircularList extends LinkedList {
#Override
public Iterator<E> iterator() {
return createIterator();
}
//create new iterator for circular process
private Iterator<E> createIterator() {
return new Iterator<E>() {
private int index = 0;
#Override
public boolean hasNext() {
//no elements when list is empty
return isEmpty();
}
#Override
public E next() {
E node = get(index);
//rotate index
index++;
if (index == size()) {
index = 0;
}
return node;
}
};
}
}`

Java.lang.NullPointerException error. Checking for a null object

So what I'm trying to do here is to check if an object exists or not through if(x.next==null) and I'm getting an error for that which won't let me access a null object. I also get the same error when trying to modify an object for e.g. x.next=y
The code is simple, it's just to implement a linked list.
Thanks!
//import SingleLinkedList1.Node;
public class SingleLinkedList2 implements ISimpleList2 {
private class Node
{ int value;
Node next; }
private Node first;
private Node last;
public void insertFront(int item) {
// TODO Auto-generated method stub
Node oldfirst = first;
// Create the new node
Node newfirst = new Node();
newfirst.value = item;
newfirst.next = oldfirst;
// Set the new node as the first node
first = newfirst;
if(oldfirst.next==null){
last=first;
}
}
public int removeFront() {
// TODO Auto-generated method stub
// Save the previous first
Node oldfirst = first;
if(oldfirst.next==null){
last=null;
}
// Follow the first's node (possibly empty)
// and set the first to that pointer
first = oldfirst.next;
// Return the value of old first
return oldfirst.value;
}
public void insertEnd(int item) {
// TODO Auto-generated method stub
Node newLast=new Node();
newLast.value=item;
last.next=newLast;
last=newLast;
}
public int removeEnd() {
// TODO Auto-generated method stub
Node oldLast=last;
Node check=new Node();
check=first;
while(check.next!=last ){
check=check.next;
}
last=check;
return oldLast.value;
}
public boolean isEmpty()
{
if(first.next==null){
return true;
}
else{
return false;
}
}
}
This is quite common.
You have to ensure that the object itself isn't null.
In your check if(x.next==null) the evaluation of x.next throws a NullPointerException because x itself is Null.
E.g. In the isEmpty method you have to check if(first==null)
I think you should check x that can be null..
like in code f(x == null), because if x is null then you will get NullPointException.

Java Generics Question

Queue12 is an interface, QueueImp12 is an implementation of Queue12. So i'm trying to test my QueueImp12 but when i run it(it compiles) in eclipse my output gets terminated in console. I believe I created ringBuffer correctly. If my test looks fine, then something must be wrong with my implementation or eclipse. Thanks
import java.util.NoSuchElementException;
public class QueueImpl12<T> implements Queue12<T>
{
private int _size, _backIdx, _frontIdx;
private static final int _defaultCapacity = 128;
private T[] _ringBuffer;
public QueueImpl12(int capacity)
{
_ringBuffer = (T[]) new Object[capacity];
clear();
}
public QueueImpl12()
{
_ringBuffer = (T[]) new Object[_defaultCapacity];
clear();
}
private int wrapIdx(int index)
{
return index % capacity();
}
public void clear()
{
_backIdx = 0;
_frontIdx = 0;
_size = 0;
}
#Override
public int capacity()
{
// TODO Auto-generated method stub
return _ringBuffer.length;
}
#Override
public int size()
{
// TODO Auto-generated method stub
return _size;
}
#Override
public boolean enqueue(T o)
{
//add o to back of queue
if(_ringBuffer.length == _size)
{
return false;
}
_ringBuffer[_backIdx] = o;
_backIdx = wrapIdx(_backIdx + 1 );
_size++;
return true;
}
#Override
public T dequeue()
{
if(_size == 0) //empty list
{
throw new NoSuchElementException();
}
T tempObj = _ringBuffer[_frontIdx]; //store frontIdx object
_ringBuffer[_frontIdx] = null;
_frontIdx++;
_size--;
return tempObj;
}
#Override
public T peek()
{
return _ringBuffer[_frontIdx];
}
}
public class P3test
{
public static<T> void main(String[] args)
{
final Queue12<T> ringBuffer = new QueueImpl12<T>();
T o = (T) new String("this");
ringBuffer.enqueue(o); //add element to the back
ringBuffer.dequeue(); //remove/return element in the front
}
}
That 'terminated' you have been seeing lately is the expected behavior when your program finishes.
Put some System.outs or asserts to verify that your code runs (here it runs, with some awful cast warnings, but runs)
final Queue12<T> ringBuffer = new QueueImpl12<T>();
T o = (T) new String("this");
ringBuffer.enqueue(o); //add element to the back
System.out.println(ringBuffer.peek());//this should print 'this' in the console\
//assertEquals('this', ringBuffer.peek());
ringBuffer.dequeue(); //remove/return element in the front
Learn how to use generics and tests. And don't put generic argument in main function, is is useless there.

Categories