Java:将对象添加到树集时会抛出异常

时间:2013-08-11 18:46:49

标签: java exception treeset

当尝试将对象添加到我的TreeSet时,会弹出此异常。

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)

我在main方法中所做的就是创建TreeSet,创建一个Object,并将其添加到集合中。

这是主要方法:

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

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

        cs.add(circle1);
    }
}

这是班级:

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);
    }
}

4 个答案:

答案 0 :(得分:3)

两个想法。

  1. 我不确定name变量实际上提供的目的是什么,因为无法从类外部访问它,也没有使用里面班级。如果未使用,请将其删除。

  2. 您的compareTo完全不正确。想想这样的比较。

    • 如何确定等效性?两个Circles如何被视为等同?
    • 如何确定自然顺序? Circles以什么方式排序?
  3. TreeSet关心其natural ordering元素。


    让我们定义一些关于Circles的法则,然后呢。

    • 当且仅当他们的半径相等时,Circle相当于另一个Circle
    • Circle等级与另一个Circle的排名较小,当且仅当他们的半径较小而另一个Circle时。
    • Circle的排名高于任何不存在的Circle

    让我们继续推进这些法律,并定义compareTo。但是,要完全实现这一点,我们需要radius的吸气剂:

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

    我正在利用Integer代替int,因为Integer也是Comparable。它使我们的compareTo更容易一些。

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

    如评论中所指出的,另一种方法也可以让你得到我们的半径和另一个对象半径的差异,这将满足Comparable的一般契约 - 如果差值为0 ,它们是等价的;如果它大于0,则它更大;它是否小于0,然后它更小。

    为此,我们将getter更改为int

    public int getRadius() {
        return radius;
    }
    

    ...并修改我们的compareTo

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

答案 1 :(得分:2)

name是静态的,因为它永远不会设置为null。我认为你误解了static的含义。

答案 2 :(得分:0)

name的{​​{1}}可能不应该是Circle,您应该在static构造函数中为其指定一个值:

Circle

答案 3 :(得分:0)

您得到NullPointerException,因为从不初始化静态变量 name 。 因此,当您调用方法 compareTo(...)时,代码的时间

return name.compareTo(c.name);
执行

,name具有空值。您正尝试通过此null值变量调用方法( comparisonTo(...)),因此这将导致抛出NullPointerException。

Addidionally,将 name 设置为static可能会在每次创建对象时导致其值被覆盖。静态变量在所有创建的对象中被认为是“唯一的”和“共同的”,因为它们的生命周期延伸到整个程序运行。更进一步,静态变量存储在计算机内存的不同位置,而不是存储局部变量或对象。