GeeCON Prague 2014*
The moose likes Java in General and the fly likes Implementing Comparable Interface with TreeSets Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Java in General
Bookmark "Implementing Comparable Interface with TreeSets" Watch "Implementing Comparable Interface with TreeSets" New topic
Author

Implementing Comparable Interface with TreeSets

Nathan Doe
Greenhorn

Joined: Oct 17, 2009
Posts: 24
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
Sheriff

Joined: Sep 28, 2004
Posts: 18874
    
  40

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


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Nathan Doe
Greenhorn

Joined: Oct 17, 2009
Posts: 24
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

Joined: Jan 28, 2008
Posts: 5575

Hi Nathan ,

Can you post your whole NameRank class? also use Code tag while posting your code
Nathan Doe
Greenhorn

Joined: Oct 17, 2009
Posts: 24
Code below
Seetharaman Venkatasamy
Ranch Hand

Joined: Jan 28, 2008
Posts: 5575

your code[post] is difficult to read.As i mentioned already use Code tag[code button] to post your code
Nathan Doe
Greenhorn

Joined: Oct 17, 2009
Posts: 24
oh sorry here it is:




And here is the second class as well

Seetharaman Venkatasamy
Ranch Hand

Joined: Jan 28, 2008
Posts: 5575

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

Joined: Oct 17, 2009
Posts: 24
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

Joined: Jan 28, 2008
Posts: 5575

it is a runtime exception nothing to do with what you said about Comparable error . only { is there in line 200
Nathan Doe
Greenhorn

Joined: Oct 17, 2009
Posts: 24
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

Joined: Jul 08, 2003
Posts: 24187
    
  34

"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!


[Jess in Action][AskingGoodQuestions]
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4659
    
    5

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

Joined: Oct 17, 2009
Posts: 24
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
Sheriff

Joined: Sep 28, 2004
Posts: 18874
    
  40

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

Joined: Oct 17, 2009
Posts: 24
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
Sheriff

Joined: Sep 28, 2004
Posts: 18874
    
  40

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
 
GeeCON Prague 2014
 
subject: Implementing Comparable Interface with TreeSets