Singly Linked LIst and Objects Newbie Question

T

Taria

Hello all,

I am creating a linked list module, and am currently developing the
linked list insert section of my program. I am still testing the
logic but I've encountered a runtime error

In short, I create a tempList of LinkedList class, I insert a value
using the insert method and when it comes back, the value is not
shown in the tempList like I thought it should have.

I think I'm calling it correctly to be initialized, and I'm surprised
the debugger I'm using hasn't blown up by now, I've ran it so many
times. I'm not understanding why the value of '3' is not reflected in
the tempList's data after calling the insert method. It returns as
null. Because it's null that's why I encounter a runtime error for
the 2nd insertation. :(

I included a copy of my program, stripped of all extraneous lines. I
apology in advance for the rough style of my program. I tried very
hard to put it into the form that SSCCE dictates. I'm not concerned
as much as to whether the linked list's logic is working as I am with
the technical aspect of objects and how to manipulate them .
(objects...I dream about this stuff now lol.)

Any help is appreciated,

-t

import java.lang.*;
public class MyProg{
public static void main(String[] arguments) {
int size = 10; //size to be read in from input of file later
LinkedList [] bucketArray = new LinkedList[ size ];

Integer three = new Integer(3);
Integer four = new Integer(4);

LinkedList tempList = new LinkedList();
tempList.insert ( three, 1 );
tempList.insert ( four, 2 );

bucketArray[0] = tempList;
}
//end of main
}

class LinkedList{
private Node head;
private int length;

public LinkedList() {
this.head = null;
this.length = 0;
}

public Object getItemAtPosition(int position) {
if (position<0 || position >= this.length){
return null;
}
Node curr = this.head;
for (int i=0;i<position;i++){
curr = curr.getNext();
}
return curr.getData();
}

public Node getNodeAtPosition(int position) {
if (position<0 || position > this.length){
return null;
}

Node curr = this.head;
for (int i=0;i < position;i++){
curr = curr.getNext(); // <-- null pointer exception
}
return curr;
}

public boolean insert (Object data,int position){
if (position<0 || position-1 > this.length ){
return false;
}

Node previous = this.getNodeAtPosition(position-1);
Node newNode = new Node(data);

if (position - 1 == 0) { //list is empty
newNode.setNext(null);
newNode.setData(data);
}
else {
newNode.setNext(previous.getNext());
previous.setNext(newNode);
}

length++;
return true;
}
}

class Node {
private Object data;
private Node next;

public Node(Object data){
this.data = data;
}

public Node(Object data,Node next){
this.data = data;
this.next = next;
}

public void setNext(Node next){
this.next = next;
}

public void setData(Object data){
this.data = data;
}

public Node getNext(){
return this.next;
}

public Object getData(){
return this.data;
}
}
 
T

Taria

I'm sorry, when I edited the program above, I left out the last curly
brace. If you insert it (the '}' thingie) at the end of the code,
then it will compile.

Sorry about that. :x

-t
 
P

Philipp Leitner

I might be missing something totally obvious here, but where in your
code are you setting the 'head' of the list? This is something that
should probably go into the block where you check for the 'first
value'.

Another sidenote: you should stick to the standard conventions of CS,
like that the first element of a list has the index '0', not '1' as in
your case (see for instance arrays, the java.util collections, ...)

/philipp
 
T

Taria

Ack, and one other thing. You need to include this line at the top:

import java.util.*;

I'm so sorry, the mouse got stuck and it didn't copy over quite right.

-t

The...cat made me do it, yea yea. (I'd rather blame the cat than
me!) :p
 
L

Lew

Philipp said:
I might be missing something totally obvious here, but where in your
code are you setting the 'head' of the list? This is something that
should probably go into the block where you check for the 'first
value'.

Another sidenote: you should stick to the standard conventions of CS,
like that the first element of a list has the index '0', not '1' as in
your case (see for instance arrays, the java.util collections, ...)

What do you mean by "CS"?

Java arrays and implementations of java.util.List are zero-based in fact, not
by convention. java.sql.PreparedStatement and ResultSet count parameters
columns respectively from one, not zero. I'm not sure one can assert the
existence of a convention.

It is enough, though, that the fact of arrays and java.util.Lists is that they
index from zero. The advice to do likewise in classes that extend or wrap
arrays or java.util.List is sound. Among other things, it eliminates the
confusing and error-prone offsets by one that abound in the OP's code.

To the OP: your main() method ought to do something to display or otherwise
prove that the contents of your list are what you expect them to be.
 
T

Taria

Ok, I did that but by doing so, I had to change the private access of
head to protected for it to work. At this point, I'm unsure and too
tired to think whether this is accepted for the 'data hiding' theory
part of Javs. Professors are adamant throughout my courses that
everytihng is declared as private.
What do you mean by "CS"?

I think he means: CS = computer science.
prove that the contents of your list are what you expect them to be.

Noted...the next time I post something of this nature, I shall include
external debugging statements within the code.

Thanks guys, for your input. :)
-t
 
X

xen

Taria,

There are many mistakes you make. Start out with what Philipp
suggested.
Your insert method should set the head, because that is the only
adding method.

Your getItemAtPosition() will generate a NullPointerException if your
head is null.

I take it your indexing range is [0, length-1].

getNodeAtPosition() uses [0, length-1] but length is allowed.
insert() uses [0, length-1] but length and length+1 are allowed

You do nothing with newNode

if (position - 1 == 0) { //list is empty
newNode.setNext(null);
newNode.setData(data);
}

should probably be

if (previous == null) {
newNode.setNext(null);
newNode.setData(data);
this.head = newNode;
}

Good luck,

xen.
 
X

xen

Also, Taria....
import java.lang.*;

You never need to import java.lang.* ;)

And perhaps nice to know, since java 1.5 you don't need to create an
Integer object if you want to pass an int as a parameter, it is
created for you.

And perhaps also nice to know, a good coding style is to put the 'most
significant' argument first in a function definition.

For example, if your method copies part of an array, you'd first
specify the array, and then the length, as in

byte[] copyOf(byte[] original, int newLength)

If your method fills a part of an array with a value, you'd first
specify the array, then the range, and then the value, as in

void fill(byte[] a, int fromIndex, int toIndex, byte val)

Likewise, you'll eventually start to write insert() methods like

void insert( int position, Object value)

instead of

void insert(Object value, int position)

It's a bit like Japanese. Boku wa, ima koko de kimi ni okane o ageru.
I, now, here, to you, money, am going to give.

xen.
 
T

Taria

Also, Taria....
import java.lang.*;

You never need to import java.lang.* ;)

And perhaps nice to know, since java 1.5 you don't need to create an
Integer object if you want to pass an int as a parameter, it is
created for you.

And perhaps also nice to know, a good coding style is to put the 'most
significant' argument first in a function definition.

For example, if your method copies part of an array, you'd first
specify the array, and then the length, as in

byte[] copyOf(byte[] original, int newLength)

If your method fills a part of an array with a value, you'd first
specify the array, then the range, and then the value, as in

void fill(byte[] a, int fromIndex, int toIndex, byte val)

Likewise, you'll eventually start to write insert() methods like

void insert( int position, Object value)

instead of

void insert(Object value, int position)

It's a bit like Japanese. Boku wa, ima koko de kimi ni okane o ageru.
I, now, here, to you, money, am going to give.

xen.

THank you Xen, I really appreciate your comments. The classes that I
take in school are so large that the programs I submit are not given
back with comments on how to improve them. Don't get me wrong, the
professors I have currently and in the past are great but they are
overloaded (imho) where they are looking over say 25 programs per
person, 60 students (2 classes) + a load of other classes they're
teaching (my first ICS class i had.) Even with a TA, Iknow they're
overloaded.

So, your comments are greatly appreciated and I will try to strive to
incorporate good programming style hints+ whatever else I need to
write coherant material.

Thanks to a few ppl on these forums, Lasse, Daniel and Roedy coming to
immediate recall, which helped me in completing this assignment. It's
due in a couple days and now at least I can try refining my program
(instead of frantically debugging). I can say there were quite a few
paramount concepts that I've learned with this assignment that failed
to stick with me in previous classes.

Now that this is done, I'm not sure what to do with my time. (well
all 1 day of freedom.) I was considering on implementing a red black
tree algorithm for my personal project to continue learning how to use
objects, and to strengthen my understanding of it because it'll be on
the next midterm. I have a bad feeling though, it sounds hard...so
maybe not. :p

I understand Japanese actually. :) Exposed to it everyday so I
recognize the structure...it's an interesting analogy and one I will
remember.

THanks again,..everyone!

-t
 
X

xen

Now that this is done, I'm not sure what to do with my time. (well
all 1 day of freedom.) I was considering on implementing a red black
tree algorithm for my personal project to continue learning how to use
objects, and to strengthen my understanding of it because it'll be on
the next midterm. I have a bad feeling though, it sounds hard...so
maybe not. :p

I understand Japanese actually. :) Exposed to it everyday so I
recognize the structure...it's an interesting analogy and one I will
remember.

Hm it seems that my algorithm and datastructure knowledge is really
limited. I've studied computer science for 3 years, but never got to
the advanced parts because of health problems. There was only an
introductory course on datastructures and algorithms in the first
year. I had never even heard of red-black trees or 2-3-4 trees or any
other of the optimizations.

If you want to study objects I think the most interesting part is
polymorphism. For example, some base abstract class defines some set
of methods including complex methods that operate on the simpler ones.
Then you subclass this base class and provide your own implementation
for the the simple methods. The complex methods that are already there
now operate on YOUR simple methods instead of those of the base class,
so you get their functionality for free.

That kind of stuff. You could study the Java Collection Framework and
its source, to see how Interface builds upon Interface and subclass
builds upon abstract class. But perhaps you've already done all that.
But then there's nothing more you need to learn about objects, I
guess.

This is also quite cool btw. You can't have nested methods in Java,
ie. you can't define a method inside a method. You also cannot define
a static class and use that, although the compiler can and does
sometimes. But you CAN define a class inside a method if you
immediately instantiate it, and have the class implement a 'nested'
method.

So for example you want to write an assertion that evaluates a complex
expression. You could define a new method:

boolean method1_checkAssert(int a, Object b) {
// calculated boolean value
return resut;
}

void method1(int a, Object b) {
// check whether the preconditions are satisfied and throw
// an AssertionError otherwise:
assert method1_checkAssert(a,b): "" + a + " must be equal to " + b;
}

But if the checkAssert method is not so big, you might do:

void method1(int a, Object b) {
assert new Object() {
boolean eval(int a, Object b) {
// calculate boolean value
return result;
}
}.eval(a,b): "" + a + " must be equal to " + b;
}

The drawback is that this creates an object but you would turn
assertions off anyway in production code. Note that you can't use any
of the method's variables unless you make them final so you must
either make them final or pass them as parameters to eval()

hope you find it interesting,
xen.
 
X

xen

So for example you want to write an assertion that evaluates a complex
expression. You could define a new method:

I forgot to mention that the expression you'd want to evaluate is not
really an expression but something you need multiple statements for to
calculate, so you can't fit it into the assert statement just like
that.
 
S

Stefan Ram

xen said:
you need multiple statements for to calculate,
so you can't fit it into the assert statement

public class Main
{ public static void main( final java.lang.String[] args )
{ assert new java.util.concurrent.Callable<java.lang.Boolean>()
{ public java.lang.Boolean call()
{ int a = 7;
++a;
return a == 9; }}.call();
java.lang.System.out.println( "ok." ); }}

Exception in thread "main" java.lang.AssertionError
at Main.main(Main.java:3)
 
L

Lew

Stefan said:
xen said:
you need multiple statements for to calculate,
so you can't fit it into the assert statement

public class Main
{ public static void main( final java.lang.String[] args )
{ assert new java.util.concurrent.Callable<java.lang.Boolean>()
{ public java.lang.Boolean call()
{ int a = 7;
++a;
return a == 9; }}.call();
java.lang.System.out.println( "ok." ); }}

Exception in thread "main" java.lang.AssertionError
at Main.main(Main.java:3)

You're scaring me.

Actually, I like this idiom a lot, except for what looks suspiciously like
abuse of the purpose of assertions. The use of an anonymous class to provide
closure-like action is a cool, if at first confusing-looking way to do things.

Java programmers must design their assertions with the thought that they will
likely be turned off in production firmly in mind.

Assertions exist primarily to enforce algorithmic invariants, although their
power admits of expanded usage based on that theme. Their highest, best use
is as part of a test strategy and framework.

Assertions are very poorly suited for run-time data validation. The rule of
thumb is to use assertions on private and package-private data and methods;
use conditional branching and exceptions on protected and public data and methods.

Note that failed assertions throw an Error, "a subclass of Throwable that
indicates serious problems that a reasonable application should not try to catch."
<http://java.sun.com/javase/6/docs/api/java/lang/Error.html>

Assertions are much more heavyweight and specialized in purpose than
validation logic and exceptions are.
 
X

xen

xen said:
you need multiple statements for to calculate,
so you can't fit it into the assert statement

public class Main
{ public static void main( final java.lang.String[] args )
{ assert new java.util.concurrent.Callable<java.lang.Boolean>()
{ public java.lang.Boolean call()
{ int a = 7;
++a;
return a == 9; }}.call();
java.lang.System.out.println( "ok." ); }}

Exception in thread "main" java.lang.AssertionError
at Main.main(Main.java:3)

Yes, generics, all the way! Only drawback is that you can't call it
with parameters. And it seems a bit unnecessary and well, useless. Why
implement an interface if it has no use AT ALL? It's not as if you're
gonna pass this object to anyone. Just a label to signify your
intention with this object? Well then you would better define your own
empty interface that doesn't place any restriction on the call method.

It surpirised me that you don't have to catch the Exception that's
defined on the call method in Callable; apparently such exceptions
only take effect if the implementing class specifies it.
 
X

xen

You're scaring me.

Actually, I like this idiom a lot, except for what looks suspiciously like
abuse of the purpose of assertions. The use of an anonymous class to provide
closure-like action is a cool, if at first confusing-looking way to do things.

Java programmers must design their assertions with the thought that they will
likely be turned off in production firmly in mind.

Assertions exist primarily to enforce algorithmic invariants, although their
power admits of expanded usage based on that theme. Their highest, best use
is as part of a test strategy and framework.

Assertions are very poorly suited for run-time data validation. The rule of
thumb is to use assertions on private and package-private data and methods;
use conditional branching and exceptions on protected and public data and methods.

Note that failed assertions throw an Error, "a subclass of Throwable that
indicates serious problems that a reasonable application should not try to catch."
<http://java.sun.com/javase/6/docs/api/java/lang/Error.html>

Assertions are much more heavyweight and specialized in purpose than
validation logic and exceptions are.

I'm currently using assertions that call an evaluation function to
uncover programming errors that originate outside of the package,
because it will be so easy to turn this checking off when it is no
longer necessary. Eventually it won't be possible for a user to
generate such errors but right now I sometimes generate them myself in
my 'debugging console' so it would be better if they were just REs.
If the package were part of a library used by other applications, I
guess I'd have to convert them to regular RuntimeExceptions...

I actually sometimes catch an assertion so that I can print debugging
information and then rethrow it.
 
S

Stefan Ram

xen said:
Yes, generics, all the way! Only drawback is that you can't call it

When I wrote this, I was not aware that you actually
had posted something like this in another posting.
So, I just wanted to show, that in Java, an expression
might contain statements.

You are right that the interface is not necessary:
I erroneously believed that it was nessary.
It surpirised me that you don't have to catch the Exception that's
defined on the call method in Callable; apparently such exceptions
only take effect if the implementing class specifies it.

It seems that an extension of a abstract method can restrict
the exceptions thrown. This seems to be suggested by

http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.3.1

It only seems to be required that

»a method declaration must not have a throws clause that
conflicts (§8.4.6) with that of any method that it overrides;«

http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.4

Also, see the example:

http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.4.3.1

Here is another example by me:

interface Example { void run() throws java.lang.Throwable; }

class Example1 implements Example
{ public void run(){ java.lang.System.out.println( "Example" ); }}

public class Main
{ public static void main( final java.lang.String[] args )
{ new Example1().run(); }}

Example
 
X

xen

»a method declaration must not have a throws clause that
conflicts (§8.4.6) with that of any method that it overrides;«

Aha. More precisely:

»A method that overrides or hides another method (§8.4.8), including
methods that implement abstract methods defined in interfaces, may not
be declared to throw more checked exceptions than the overridden or
hidden method.«

http://java.sun.com/docs/books/jls/third_edition/html/classes.html#308526

So it can't become more, but it can become less.
 
H

Hunter Gratzner

Now that this is done, I'm not sure what to do with my time. (well
all 1 day of freedom.)

Roedy has a list of potential student projects on his site. I don't
know if some are one day projects.

But if you are really interested, why not start a larger project on
the side, and work on it whenever you find some time? The few
programming exercises you typically get at school don't make you a
programmer, they are to show concepts and keep you busy.
 
D

Daniel Pitts

Hunter said:
Roedy has a list of potential student projects on his site. I don't
know if some are one day projects.

But if you are really interested, why not start a larger project on
the side, and work on it whenever you find some time? The few
programming exercises you typically get at school don't make you a
programmer, they are to show concepts and keep you busy.
Not only that, but they tend to teach you how to write bad code, and
clarify it with redundant comments. Just wrote a blog about that
actually...
<http://virtualinfinity.net/wordpress/uncategorized/2007/10/02/writing-as-an-artform/>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top