Bungalo Soldier
Bungalo Soldier

Reputation: 154

Java: When adding an object to a tree set exception gets thrown

When try to add an object to my TreeSet, this exception pops up.

Exception in thread "main" java.lang.NullPointerException
    at Circle.compareTo(Shape.java:47)
    at Circle.compareTo(Shape.java:23)
    at java.util.TreeMap.compare(Unknown Source)
    at java.util.TreeMap.put(Unknown Source)
    at java.util.TreeSet.add(Unknown Source)
    at CircleTreeSet.main(CircleTreeSet.java:24)

All I'm doing in my main method is creating the TreeSet, creating a Object, and adding it to the set.

Here is the main method:

class CircleTreeSet {
    public static void main(String[] args) {
        TreeSet<Circle> cs = new TreeSet<Circle>();

        Circle circle1 = new Circle("circle1", 1);

        cs.add(circle1);
    }
}

Here is the class:

class Circle extends Shape implements Comparable<Circle> {
    private static String name;
    private int radius;

    Circle(String n, int r) {
        super(n);
        radius = r;
    }

    public double area() {
        return Math.PI * radius * radius;
    }

    public double perim() {
        return 2 * Math.PI * radius;
    }

    public int compareTo(Circle c) {
        return name.compareTo(c.name);
    }
}

Upvotes: 1

Views: 2694

Answers (4)

Nick Louloudakis
Nick Louloudakis

Reputation: 6005

You get a NullPointerException, as you never initialize the static variable name. As a result, when you invoke the method compareTo(...), the time the code

return name.compareTo(c.name);

is executed, name has a null value. You are trying to invoke a method (comparedTo(...)) via this null-valued variable, so this will result in a NullPointerException throwing.

Addidionally, having the name set as static will probably result in its value overwriting everytime you create an object. Static variables are considered as "unique" and "common" in a sense among all created objects, as their lifetime extends across the entire run of the program. To take it one step further, static variables are stored in a different place of computer memory than local variables or objects are stored.

Upvotes: 0

Makoto
Makoto

Reputation: 106430

Two thoughts.

  1. I'm not sure what purpose the name variable would actually serve, since there's no way to access it from outside of the class, nor is it used inside the class. If it's not used, remove it.

  2. Your compareTo is simply incorrect. Think of a comparison like this.

    • How do I determine equivalence? How are two Circles deemed equivalent?
    • How do I determine the natural ordering? In what way are Circles ordered by?

A TreeSet cares about the natural ordering of its elements.


Let's define some laws about Circles, then.

  • A Circle is equivalent to another Circle if and only if their radius is equivalent.
  • A Circle is lesser in rank to another Circle if and only if their radius is lesser rank to another Circle.
  • A Circle is higher in rank to any nonexistent Circle.

Let's move forward with those laws, and define compareTo. To fully complete this, though, we need a getter for radius:

public Integer getRadius() {
    return Integer.valueOf(radius);
}

I'm leveraging Integer instead of int, since Integer is also Comparable. It makes our compareTo a little easier.

public int compareTo(final Circle other) {
    if(other == null) {
        return 1;
    } else {
        return Integer.valueOf(radius).compareTo(other.getRadius());
    }
}

An alternative way, as pointed out in the comments, would also allow you to take the difference of our radius, and the other object's radius, which would satisfy the general contract for Comparable - if the difference is 0, they're equivalent; if it's greater than 0, then it's larger; is it's less than 0, then it's smaller.

To do that, we change our getter to return int:

public int getRadius() {
    return radius;
}

...and modify our compareTo as such:

public int compareTo(final Circle other) {
    if(other == null) {
        return 1;
    } else {
        return radius - other.getRadius();
    }
}

Upvotes: 3

PoByBolek
PoByBolek

Reputation: 3915

The name of your Circle should probably not be static and you should assign a value to it in the Circle constructor:

class Circle extends Shape implements Comparable<Circle> {
    private String name;
    private int radius;

    Circle(String n, int r) {
        this.name = n; // this is crucial
        this.radius = r;
    }

    public int compareTo(Circle other) {
        return name.compareTo(other.getName());
    }

    public String getName() {
        return name;
    }
}

Upvotes: 0

Robin Green
Robin Green

Reputation: 33063

name is static and is null because it is never set. I think you have misunderstood the meaning of static.

Upvotes: 2

Related Questions