Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Implementing Comparable Interface with TreeSets

 
Nathan Doe
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm working on this project that I need to override the compareTo() method in the Comparable interface in one class and create a new TreeSet in another using the first class. What i've written eclipse doesn't have a problem with, but when I try to create a TreeSet in the second class it I get this error:

Exception in thread "main" java.lang.ClassCastException: NameRank cannot be cast to java.lang.String
at NameRank.compareTo(NameRank.java:1)
at java.util.TreeMap.put(TreeMap.java:545)
at java.util.TreeSet.add(TreeSet.java:238)
at CollectionsTest.main(CollectionsTest.java:213)

my compareTo() class is supposed to set the “Natural Ordering” of the class to alphabetical by the Name field. mine looks like this:
public int compareTo(String o)
{
int res = 0;
if (this.name.compareTo(o) < 0)
{
res = -1;
}
if (this.name == o)
{
res = 0;
}
if (this.name.compareTo(o) > 0)
{
res = 1;
}
return res;
}


Any help would be appreciated.
 
Henry Wong
author
Marshal
Pie
Posts: 21115
78
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your NameRank class seems to implements Comparator<String> ? That's kinda wrong -- it should implement Comparator<NameRank>. After all, your TreeSet contains NameRank objects, so a NameRank object needs to compare to another NameRank object.

Henry
 
Nathan Doe
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I changed NameRank class to:

public class NameRank implements Comparable <NameRank>

and the compareTo() to:

public int compareTo(NameRank o)
{
int res = 0;

if (this.name.compareTo(o.name) < 0)
{
res = -1;
}
if (this.name == o.name)
{
res = 0;
}
if (this.name.compareTo(o.name) > 0)
{
res = 1;
}

return res;
}


but i am still getting the error when i try to run my CollectionsTest Class (which is the second class)

 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Java Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Nathan ,

Can you post your whole NameRank class? also use Code tag while posting your code
 
Nathan Doe
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Code below
 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Java Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
your code[post] is difficult to read.As i mentioned already use Code tag[code button] to post your code
 
Nathan Doe
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
oh sorry here it is:




And here is the second class as well

 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Java Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
your comparable implementation looks ok to me . sorry ! can you figure out that in which line number you get an compile time error ?
 
Nathan Doe
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The Compile time error occurs in the CollectionsTest Class on line 200. The error message reads:

Exception in thread "main" java.lang.NullPointerException
at java.util.TreeMap.put(TreeMap.java:541)
at java.util.TreeSet.add(TreeSet.java:238)
at CollectionsTest.main(CollectionsTest.java:200)
 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Java Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
it is a runtime exception nothing to do with what you said about Comparable error . only { is there in line 200
 
Nathan Doe
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm getting an error there because thats when I'm trying to actually add something the the TreeSet. Which from the research i've done means my compareTo() method isn't written right...
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24211
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"Research" or no, the stack trace doesn't lie. It shows exactly what code is excuting when the error occurs. It shows you calling add() on a TreeSet at line 200 of your program (it's numbered 201 here but that's probablyjust a cut-and-paste thing.) TreeSet.add() calls TreeMap.put() (since a TreeSet is just a TreeMap internally) and then the NullPointerException occurs. What this means is that you're calling add() with "null" as an argument. That's pretty obvious -- the array "last" is allocated at a fixed size, but the number of elements added to it is determined by an external file. The loop that reads from the file is pretty dodgy, and all those empty catch blocks mean that if something goes wrong and not a single line is properly read, we won't actually know about it; the errors will just be ignored. "compareTo" is absolutely not involved.

Note that you can add "null" to any List implementation legally, and HashSet (HashMap) has a special provision for adding a null key. Of the collections you use, then, TreeSet is the first one sensitive to "null" being added, so that's where the problem appears. But frankly, who knows where the nulls are coming from. Is the array supposed to be exactly the right size to hold the records from the file? Why not size the array based on the number of records you find, instead (collect the lines in a List, and only when you know the count, then allocate an array.)

So to reiterate my main points:

1) Stack traces don't lie. Don't imagine the problem is somewhere else when the stack trace tells you precisely where the error occurs.
2) Read the Javadocs for the classes you use so you know (for example) how they handle nulls!
3) Computers are NOT mysterious. They are machines with absolutely deterministic behavior. If you don't know why something happens, find out.
4) NEVER HAVE EMPTY CATCH BLOCKS!

And one more point: never, ever, write a couple hundred lines of code and then push them off a cliff, as you've done here. There's too much code here to now go back and fix. Write a few, compile, test. Then write a few more, compile, and test. Don't move forward with step 6 until step 5 is perfect. Add print statements temporarily to help you understand exactly what your code is doing, or step through it with a debugger. Never be mystified -- always make sure you understand!
 
Pat Farrell
Rancher
Posts: 4678
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Seriously, use JUnit. Both Eclipse and Netbeans will generate the tests for you with a click or two.

Do it early, test often.

It really will make your life easier.
 
Nathan Doe
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The arrays are sized to two exact files my professor gave us and the program is built to only read those two files. What I don't get is how can there be a Null Pointer Exception if every one of the previous data structures (Array List, Hash Set, Linked List) can read the data fine before getting to the TreeSet? When I comment out the whole TreeSet benchmarking section the program runs fine, just when it is uncommented do I get a null pointer exception. Is there some kind of special rule for TreeSets I don't know about and need to implement in my code?

- Nathan
 
Henry Wong
author
Marshal
Pie
Posts: 21115
78
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nathan Doe wrote:The arrays are sized to two exact files my professor gave us and the program is built to only read those two files. What I don't get is how can there be a Null Pointer Exception if every one of the previous data structures (Array List, Hash Set, Linked List) can read the data fine before getting to the TreeSet? When I comment out the whole TreeSet benchmarking section the program runs fine, just when it is uncommented do I get a null pointer exception. Is there some kind of special rule for TreeSets I don't know about and need to implement in my code?


Step 1. Stop speculating. Use the NPE to locate the exact line of the exception. Then add logging, or printouts to confirm that the reference is actually null. Confirm the null, then figure out how it happened.

Henry
 
Nathan Doe
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, so it looks like I made the Array "last" one spot too big which the TreeSet didn't like. Im guessing that TreeSets don't accept null values for positions in them where as the other data structures just store the null value.

Thanks for the help,

- Nathan
 
Henry Wong
author
Marshal
Pie
Posts: 21115
78
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nathan Doe wrote:Ok, so it looks like I made the Array "last" one spot too big which the TreeSet didn't like. Im guessing that TreeSets don't accept null values for positions in them where as the other data structures just store the null value.


I believe, and I may be wrong, the TreeSet class can take a null, if you are using a Comparator. If you are using Comparable elements, then you'll get a NullPointerException because the TreeSet can't compare the element.

Henry
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic