Unsorted Arrays having trouble controlling the array.
I have to create a couple methods from all these classes such as finding the lowest and largest numbers, sum of all the values in the list, and average. You can only add them to the UnsortedArrayList class. Not able to use any arguments.
I've done the lowest and largest...but I wanted to make sure I'm going about it correctly.
Here is my code:
Code :
public abstract class DataElement{
public abstract boolean equals(DataElement otherElement);
public abstract int compareTo(DataElement otherElement);
public abstract void makeCopy(DataElement otherElement);
public abstract DataElement getCopy();
}
Code :
public class IntElement extends DataElement
{
protected int number;
public IntElement()
{
number = 0;
}
public IntElement(int num)
{
number = num;
}
public IntElement(IntElement obj)
{
this.number = obj.getNum();
}
public void setNum(int num)
{
number = num;
}
public int getNum()
{
return number;
}
public boolean equals(DataElement obj)
{
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
IntElement temp = (IntElement)obj;
return (number == temp.number);
}
public int compareTo(DataElement obj)
{
IntElement temp = (IntElement)obj;
if (number < temp.number) return -1;
else if (number > temp.number) return 1;
else return 0;
}
public void makeCopy(DataElement obj)
{
IntElement temp = (IntElement)obj;
number = temp.number;
}
public DataElement getCopy()
{
DataElement temp = new IntElement(number);
return temp;
}
}
Code :
public abstract class ArrayListClass{
protected int length; //to store length of the list
protected int maxSize; // to store max size of list
protected DataElement[] list; //array to hold list elements
public ArrayListClass(){
length = 0;
maxSize = 100;
DataElement[] list = new DataElement[maxSize];
}
public ArrayListClass(int size){
length = 0;
maxSize = size;
DataElement[] list = new DataElement[maxSize];
}
public ArrayListClass(ArrayListClass obj){
this.length = obj.length;
this.maxSize = obj.maxSize;
this.list = obj.list;
}
public boolean isEmpty()
{
return (length == 0);
}
public boolean isFull()
{
return (length == maxSize);
}
public int listSize()
{
return length;
}
public int maxListSize()
{
return maxSize;
}
public void print()
{
for(int i = 0; i < length; i++)
System.out.print(list[i] + " ");
System.out.println();
}
public boolean isItemAtEqual(int location, DataElement item)
{
return (list[location].equals(item));
}
public boolean insertAt(int location, DataElement insertItem)
{
boolean rc = true;
if(location < 0 || location >= maxSize) //out of range
rc = false;
else
if(length >= maxSize) //list is full
rc = false;
else
{
for(int i = length; i > location; i--)
list[i] = list[i - 1]; //move the elements down
list[location] = insertItem.getCopy(); //insert the item at
//the specified position
length++; //increment the length
}
return rc;
}//end insertAt
public boolean insertEnd(DataElement insertItem)
{
boolean rc = true;
if(length >= maxSize) //the list is full
rc = false;
else
{
list[length] = insertItem.getCopy(); //insert item
//at end
length++; //increment the length
}
return rc;
}//end insertEnd
public boolean removeAt(int location)
{
boolean rc = true;
if(location < 0 || location >= length) //out of range
rc = false;
else
{
for(int i = location; i < length - 1; i++)
list[i] = list[i + 1];
list[length - 1] = null;
length--;
}
return rc;
}//end removeAt
public DataElement retrieveAt(int location)
{
if(location < 0 || location >= length) //out of range
{
return null;
}
else
return list[location].getCopy();
}//end retrieveAt
public boolean replaceAt(int location, DataElement repItem)
{
boolean rc = true;
if(location < 0 || location >= length) //out of range
rc = false;
else
list[location].makeCopy(repItem);
return rc;
}//end replaceAt
public void clearList()
{
for(int i = 0; i < length; i++)
list[i] = null;
length = 0;
}//end clearList
public abstract int seqSearch(DataElement searchItem);
public abstract boolean insert(DataElement insertItem);
public abstract void remove(DataElement removeItem);
}
Code :
public class UnsortedArrayList extends ArrayListClass{
public UnsortedArrayList(){
super();
}
public UnsortedArrayList(int size){
super(size);
}
public UnsortedArrayList(UnsortedArrayList obj){
super(obj);
}
public int seqSearch(DataElement searchItem)
{
int loc;
for(loc = 0; loc < length; loc++)
if(list[loc].equals(searchItem))
return loc; //found
return -1; //not found
}//end seqSearch
// insert unique - no duplicates
public boolean insert(DataElement insertItem)
{
boolean rc = true;
int loc;
if(length == 0) //list is empty
list[length++] = insertItem; //insert the item and
//increment the length
else
if(length == maxSize) //list full
rc = false;
else
{
loc = seqSearch(insertItem);
if(loc == -1) //the item to be inserted
//does not exist in the list
//then insert it
list[length++] = insertItem.getCopy();
else
rc = false; //duplicates not allowed
}
return rc;
}//end insertUnq
public void remove(DataElement removeItem)
{
boolean rc = true;
int loc;
if(length == 0) //empty list
rc = false;
else
{
loc = seqSearch(removeItem);
if(loc != -1)
removeAt(loc);
else
rc = false; //not in the list
}
}//end remove
// insert duplicates
public boolean insertDup(DataElement insertItem)
{
boolean rc = true;
int loc;
if(length == 0) //list is empty
list[length++] = insertItem; //insert the item and
//increment the length
else
if(length == maxSize) //list full
rc = false;
else
list[length++] = insertItem.getCopy();
return rc;
}//end insertDup
public int min(){
int lowest = 101;
for(int i = 1; i < list.length; i++){
if(list[i].compareTo(list[i-1]) == 1){
IntElement temp = (IntElement)list[i].getCopy();
lowest = temp.getNum();
}
}
return lowest;
}
public int max(){
int highest = 0;
for(int i = 1; i < list.length; i++){
if(list[i].compareTo(list[i-1]) == -1){
IntElement temp = (IntElement)list[i].getCopy();
highest = temp.getNum();
}
}
return highest;
}
}
Thanks!
Re: Unsorted Arrays having trouble controlling the array.
I got further into the program but now it's telling me I get an error about a specific line. I'm trying to generate 100 random numbers between 1 and 100 and put them into the ArrayListClass log. Then have the console output tell which is the highest number of the log,lowest, sum of all numbers in the log, and the avg.
Code :
public class TestArray{
public static void main(String[] args){
ArrayListClass log = new UnsortedArrayList(100);
boolean flag = false;
int randomNum = 20;
DataElement temp = new IntElement(randomNum);
flag = log.insert(temp);
if(flag == true)
System.out.println("true");
else
System.out.println("false");
}
}
When I do log.insert(randomNum); it tells me there is a NullPointerException and points me straight to the UnsortedArrayListClass to the insert(DataElement insertItem) method. Within the method it's saying the line below is the problem. Why is this?
list[length++] = insertItem; //insert the item and
//increment the length
I thought I was first creating a ArrayListClass obj with 100 elements for the array, and then putting randomNumbers in the DataElement obj using the constructor. Then I'm trying to insert that DataElement into the array, and that's when I get the error.
Re: Unsorted Arrays having trouble controlling the array.
Quote:
Originally Posted by
orbin
...
When I do log.insert(randomNum); it tells me there is a NullPointerException and points me straight to the UnsortedArrayListClass to the insert(DataElement insertItem) method. Within the method it's saying the line below is the problem. Why is this?
Since it is telling you at run time that the value of the list reference variable is null, then it must be that it was declared somewhere that the compiler knows about it, but was never given a value to make it something other than null.
So, like fishes at spawning time, I suggest we start at the bottom and work our way upstream.
I think it is telling you that, In your UnsortedArrayList.insert() method, the "list" variable that it is seeing has a null value.
If there is any doubt, you can verify this by printing out its value at that point.
Code java:
//In UnsortedArrayList.java
//
// insert unique - no duplicates
public boolean insert(DataElement insertItem)
{
boolean rc = true;
int loc;
if(length == 0) { //list is empty
System.out.println("in UnsortedArrayList.insert: list = " + list);
list[length++] = insertItem; //insert the item and
}
//increment the length
.
.
.
Now, if it says you have a null value at this point, you scratch your head and mutter, "How the heck can that happen?" (At least that's what I do, but maybe that's just me.)
Anyhow...
Backtrack through your logic and your code and see if you can make the program tell you where it is doing what you think it is supposed to do.
In main() you invoked the constructor for log well before trying to insert something, right? Well you can instrument it, just to make sure it's following the path you think it should. (This program is so straightforward that it probably wouldn't be necessary to trace it like this,but I like to follow the code up to the place of the problematic behavior.):
Code java:
// In TestArray.java
public class TestArray{
public static void main(String[] args){
ArrayListClass log = new UnsortedArrayList(100);
System.out.println("in main(): log = " + log);
boolean flag = false;
int randomNum = 20;
DataElement temp = new IntElement(randomNum);
System.out.println("in main(): Calling log.insert(" + temp + ")");
flag = log.insert(temp);
.
.
.
Now, you can put code in the constructor to make sure it actually went where you thought it should:
Code java:
//In UnsortedArrayList.java
public UnsortedArrayList(int size){
super(size);
System.out.println("In UnsortedArrayList(size) constructor, size = "
+ size
+ ", list = "
+ list);
}
See the plan? Make the code verbose enough to tell you exactly where it is when it is seeing the stuff that it prints. My point being, that if it gets to the insert method seeing a null value for the array reference variable, there must have been a breakdown somewhere along the way where you thought you had caused it to have a non-null value.
If you need to go further upstream to see where the problem is, then you can instrument the super() constructor from UnsignedArrayList constructor:
Code java:
// In ArrayListClass.java
public ArrayListClass(int size) {
length = 0;
maxSize = size;
DataElement[] list = new DataElement[maxSize];
System.out.println("In ArrayListClass(size) constructor, size = "
+ size + ", list = " + list);
}
I know it seems kind of messy to sprinkle all of those print statements throughout the landscape and affecting several different files (and, of course it always takes me an iteration or three to remember where they all are so that I can go back and delete them once I have fixed the error), but the important thing is to have a systematic method of tracing (back to the beginning, if necessary) through your code. Maybe your approach will be different, but make sure the print statements tell you exactly where they are as well as what they are printing. Just printing a bunch of numbers with no kind of label is bound to create frustration. (At least it always did for me.)
Use of a debugger might be more elegant, but at beginning level, I think it's appropriate to practice writing code that makes the program tell us what it is seeing, and equally importantly, telling us how it got to wherever it ends up.
Cheers!
Z
Re: Unsorted Arrays having trouble controlling the array.
Thank you for taking the time to write that out. That makes a lot of sense now that you brought it to my attention. I've never really created troubleshooting checkpoints unless it was something very miniscule. However, I'm still having an issue after creating those checkpoints you mentioned.
Code :
--------------------Configuration: <Default>--------------------
In ArrayListClass(size) constructor, size = 100, list = [LDataElement;@1f183871
In UnsortedArrayList(size) constructor, size = 100, list = null
in main(): log = UnsortedArrayList@6f2192a9
in main(): Calling log.insert(IntElement@523ce3f)
In insert method : length = 0insert item = IntElement@523ce3f
Exception in thread "main" java.lang.NullPointerException
at UnsortedArrayList.insert(UnsortedArrayList.java:40)
at TestArray.main(TestArray.java:16)
Process completed.
Above is what I ended up with. This might be a lack of experience in my fundamentals but why is it printing the arraylist class constructor first, when it goes through unsortedarraylist first? Another thing I noticed, is that all of a sudden, an address reference is applied to the list variable. Is it applying the unsorted class list which is null, or the ArrayListClass which is an address? I'm still having trouble understanding what's going on, or the proper way to read this.
edit: I edited the output and put one more println in the insert method itself.
Re: Unsorted Arrays having trouble controlling the array.
Quote:
Originally Posted by
orbin
Above is what I ended up with. This might be a lack of experience in my fundamentals but why is it printing the arraylist class constructor first, when it goes through unsortedarraylist first?
Your main() program calls the UnsortedArrayList constructor, right? Well, the UnsortedArrayList class is derived from the ArrayList class, right? What is the very first thing that the UnsortedArrayList constructor does? It calls the ArrayList constructor. That's what the "super()" thing does: Calls the constructor for the "superclass of UnsortedArrayList. The first statement in a derived class constructor is to call the constructor of its superclass. And, yes, that is fundamental.
Quote:
Originally Posted by
orbin
Code :
In ArrayListClass(size) constructor, size = 100, list = [LDataElement;@1f183871
In UnsortedArrayList(size) constructor, size = 100, list = null
OK! This is the key! The ArrayListClass constructor assigns a value to a reference variable named "list"
Now, list is an array of DataElement objects. When you use the name of an array in a println statement, it does not print the contents of the array; it prints something about the name of the array and a hashcode that the compiler will use to get to the memory occupied by the array. Now, to us mere humans doing primitive debugging by printing stuff out, that hashcode value, in and of itself, isn't terribly important.
What is important is that, if we have declared a reference variable and haven't assigned any value to it, its value is null (doesn't point the compiler to memory). If the reference variable has a null value, there is no memory associated with the array, and if our program tries to store something in the array, we get the NPE (Null Pointer Exception).
On the other hand, if we have assigned a value to the reference variable that is the name of an array (maybe with a new statement) your program can assign values to members of the array.
So: Look at the first two things that the print statements show us:
In the ArrayList class constructor, there is a reference variable named list, and the new operator has assigned a value. The actual value is kind of irrelevant to us except for the very important fact that it is not null. Look at all of the code. Where is the list variable declared? Where is it given a value? (Answer: it is a local variable inside that constructor. It is given a value by the new statement.)
Now, in the UnsignedArrayList constructor, after the ArrayList constructor has returned, we find that there is a list reference variable whose value is null. Look at all of the code. Where is the list variable declared? Where is given a value?
Cheers!
Z
Re: Unsorted Arrays having trouble controlling the array.
Thanks once again. I managed to solve the problem by declaring it into my UnsortedArrayList class.
Code :
public abstract class ArrayListClass{
protected int length; //to store length of the list
protected int maxSize; // to store max size of list
protected DataElement[] list; //array to hold list elements
public ArrayListClass(){
length = 0;
maxSize = 100;
DataElement[] list = new DataElement[maxSize];
}
public ArrayListClass(int size){
length = 0;
maxSize = size;
DataElement[] list = new DataElement[maxSize];
}
public ArrayListClass(ArrayListClass obj){
this.length = obj.length;
this.maxSize = obj.maxSize;
this.list = obj.list;
}
public boolean isEmpty()
{
return (length == 0);
}
public boolean isFull()
{
return (length == maxSize);
}
public int listSize()
{
return length;
}
public int maxListSize()
{
return maxSize;
}
public void print()
{
for(int i = 0; i < length; i++)
System.out.print(list[i] + " ");
System.out.println();
}
public boolean isItemAtEqual(int location, DataElement item)
{
return (list[location].equals(item));
}
public boolean insertAt(int location, DataElement insertItem)
{
boolean rc = true;
if(location < 0 || location >= maxSize) //out of range
rc = false;
else
if(length >= maxSize) //list is full
rc = false;
else
{
for(int i = length; i > location; i--)
list[i] = list[i - 1]; //move the elements down
list[location] = insertItem.getCopy(); //insert the item at
//the specified position
length++; //increment the length
}
return rc;
}//end insertAt
public boolean insertEnd(DataElement insertItem)
{
boolean rc = true;
if(length >= maxSize) //the list is full
rc = false;
else
{
list[length] = insertItem.getCopy(); //insert item
//at end
length++; //increment the length
}
return rc;
}//end insertEnd
public DataElement retrieveAt(int location)
{
if(location < 0 || location >= length) //out of range
{
return null;
}
else
return list[location].getCopy();
}//end retrieveAt
public boolean replaceAt(int location, DataElement repItem)
{
boolean rc = true;
if(location < 0 || location >= length) //out of range
rc = false;
else
list[location].makeCopy(repItem);
return rc;
}//end replaceAt
public void clearList()
{
for(int i = 0; i < length; i++)
list[i] = null;
length = 0;
}//end clearList
public abstract int seqSearch(DataElement searchItem);
public abstract boolean insert(DataElement insertItem);
public abstract void remove(DataElement removeItem);
public abstract int min();
public abstract boolean removeAt(int location);
}
Code :
public class UnsortedArrayList extends ArrayListClass{
public UnsortedArrayList(){
super();
}
public UnsortedArrayList(int size){
super(size);
list = new IntElement[size];
length = 0;
}
public UnsortedArrayList(UnsortedArrayList obj){
super(obj);
}
public int seqSearch(DataElement searchItem)
{
int loc;
for(loc = 0; loc < length; loc++)
if(list[loc].equals(searchItem))
return loc; //found
return -1; //not found
}//end seqSearch
// insert unique - no duplicates
public boolean insert(DataElement insertItem)
{
boolean rc = true;
int loc;
if(length == 0){
//list is empty
list[length++] = insertItem; } //insert the item and
//increment the length
else
if(length == maxSize) //list full
rc = false;
else
{
}
return rc;
}//end insertUnq
public void remove(DataElement removeItem)
{
boolean rc = true;
int loc;
if(length == 0) //empty list
rc = false;
else
{
loc = seqSearch(removeItem);
if(loc != -1)
removeAt(loc);
else
rc = false; //not in the list
}
}//end remove
// insert duplicates
public boolean insertDup(DataElement insertItem)
{
boolean rc = true;
int loc;
if(length == 0) //list is empty
list[length++] = insertItem; //insert the item and
//increment the length
else
if(length == maxSize) //list full
rc = false;
else
list[length++] = insertItem.getCopy();
return rc;
}//end insertDup
public int min(){
int lowest = 0;
for(int i = 0; i<100; i++){
if(list[i].compareTo(list[i+1]) == 1){
IntElement temp = (IntElement)(list[i].getCopy());
lowest = temp.getNum();
}
if(list[i].compareTo(list[i+1]) == -1)
{
IntElement temp2 = (IntElement)(list[i+1].getCopy());
lowest = temp2.getNum();
}
}
return lowest;
}
public boolean removeAt(int location)
{
boolean rc = true;
if(location < 0 || location >= length) //out of range
rc = false;
else
{
for(int i = location; i < length - 1; i++)
list[i] = list[i + 1];
list[length - 1] = null;
length--;
}
return rc;
}//end removeAt
}
Code :
public class TestArray{
public static void main(String[] args){
ArrayListClass log = new UnsortedArrayList(100); //created a new object which declares an array of 100 DataElement objects
for(int i = 0; i<100; i++){
int randomNum = (int)(1 + 100*Math.random()); //generates a random number
IntElement temp = new IntElement(randomNum); //creates a new IntElement object which sets the number
System.out.println(randomNum); //prints out what the random number is
log.insert(temp); //inserts the IntElement object into the log array
}
System.out.println("Inserted 100 randomly generated numbers into the log.");
System.out.println(log.min());
}
}
I'm having a lot of trouble with this program because I find it very difficult to be controlling an array from an object which keeps it hidden on many levels. I can control an array if I'm given the array itself, but controlling it through the methods of the object makes it very difficult for me to see how to move stuff around.
Now I'm trying to write a proper method to find the smallest number within the array of DataElements.
This is what I have so far... but clearly it's not working since it always returns 0 which is what I declared it as. I tried to take it step by step..but the issue I'm having is using the compareTo method.
Code :
public int min(){
int lowest = 0;
for(int i = 0; i<100; i++){
if(list[i].compareTo(list[i+1]) == 1){
IntElement temp = (IntElement)(list[i].getCopy());
lowest = temp.getNum();
}
if(list[i].compareTo(list[i+1]) == -1)
{
IntElement temp2 = (IntElement)(list[i+1].getCopy());
lowest = temp2.getNum();
}
}
return lowest;
}
I know that I'm controlling a DataElement in the [0] position of the array. Then I use the compareTo method, because I want to compare position 0 in the array to position 1 in the array. If position 0 is greater than it returns a -1. So obviously I want the one that says less than, so it returns a 1. Once it returns a 1, i get a copy of the DataElement and cast it to become a IntElement, and put that into the ref variable temp. Then since temp is a IntElement I use the getNum method and save it to the lowest variable. What am I doing wrong here? I believe it has something to do with the if statement. I can't seem to wrap my head around it. Thanks once again for taking the time to explain everything to me.
Re: Unsorted Arrays having trouble controlling the array.
Quote:
Originally Posted by
orbin
I managed to solve the problem...
In my opinion, your fix wasn't a very good fix, stylistically speaking, but you did at least get the "list" variable initialized.
So...
Maybe we can start with where you are now, and later on, we can get back to your original code (if you haven't figured it out by then).
Anyhow...
Quote:
Originally Posted by
orbin
...
I know that I'm controlling a DataElement in the [0] position of the array. Then I use the compareTo method, because I want to compare position 0 in the array to position 1 in the array....
Running your current code, I find that it reports that it inserted 100 elements. However,
Code :
.
.
.
bunch of numbers
.
.
.
41
19
70
13
77
5
83
Inserted 100 randomly generated numbers into the log.
Exception in thread "main" java.lang.NullPointerException
at IntElement.compareTo(IntElement.java:46)
at UnsortedArrayList.min(UnsortedArrayList.java:90)
at TestArray.main(TestArray.java:15)
So, now what?
Here's what: Go back and find why IntElement.compareTo() is throwing the NPE. IntElement.compareTo() is called by UnsortedArrayList.min(), which is called from TestArray.main().
For starters:
Code java:
public int compareTo(DataElement obj)
{
System.out.println("In IntElement.compareTo(obj): obj = " + obj);
IntElement temp = (IntElement)obj;
if (number < temp.number) return -1;
else if (number > temp.number) return 1;
else return 0;
}
Now I get:
Code :
In IntElement.compareTo(obj): obj = null
Exception in thread "main" java.lang.NullPointerException
.
.
.
Back up to the place where compareTo() is called. Namely in UnsortedArrayList.min():
Code java:
public int min() {
System.out.println("UnsortedArrayList.min(): list = " + list);
int lowest = 0;
for(int i = 0; i<100; i++){
System.out.println("UnsortedArrayList.min(): list[" +
i + "] = " + list[i] +
", list[" + (i+1) + "] = " + list[i+1]);
if(list[i].compareTo(list[i+1]) == 1){
IntElement temp = (IntElement)(list[i].getCopy());
lowest = temp.getNum();
}
Now I get:
Code :
Inserted 100 randomly generated numbers into the log.
UnsortedArrayList.min(): list = [LIntElement;@9931f5
UnsortedArrayList.min(): list[0] = IntElement@19ee1ac, list[1] = null
In IntElement.compareTo(obj): obj = null
Exception in thread "main" java.lang.NullPointerException
We see that list is not null. That's no surprise, since if it were, the previous stuff would have crashed, right?
Anyhow...
We see that list[0] has a value, but list[1] is still null. Where in your code did you expect that all of the list[i] variables would be given values? UnsortedArrayList.insert() or where? Look at the code. Really. Look. (If you can't see the problem, instrument that function with a print statement or two.)
See how it goes? When you get a problem, look at the code. If you think you need to make a bunch of changes (or if you want to start all over again), then go for it.
But if you want to understand how that code got to that point where the NPE was thrown, try to track it down. Maybe it's just a simple programming error and not one of those abstract things. (In other words: Don't panic!)
Anyhow, here's my suggestion:
Pick one thing. Fix it. Maybe in the process of fixing it you will come to an understanding of other problems that you will be able to fix before they raise their ugly heads (or at least to recognize the effects when they happen in another context).
Tattooed on my psyche is part of a verse from a "Blindside" song that reminds me of my approach to debugging. It's a first-person description of a battle between me and the bug:
"I grab you by the throat
And we come crashing down through the window
On the dirt ground below
And we wrestle in the mud and the blood and the beer"
---"Fell in Love With the Game"
(A really tender love ballad.)
Oh, the humanity! All that mud! All that blood! All that beer!
Cheers!
Z