1

当尝试将对象添加到我的 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)

我在我的主要方法中所做的只是创建 TreeSet、创建一个对象并将其添加到集合中。

下面是主要方法:

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

4 回答 4

3

两个想法。

  1. 我不确定该name变量的实际用途是什么,因为无法从类外部访问它,也无法在类内部使用它。如果不使用,请将其删除。

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

    • 如何确定等效性?两个如何被Circles认为是等价的?
    • 如何确定自然排序?以什么方式Circles排序?

ATreeSet关心其元素的自然顺序


那么,让我们定义一些关于 的定律Circles

  • 当且仅当它们的半径相等时, A才Circle等效于另一个。Circle
  • 当且仅当它们的半径比另一个小时, ACircle的等级比另一个小。CircleCircle
  • ACircle的等级高于任何不存在Circle的 。

让我们继续推进这些法律,并定义compareTo. 但是,要完全完成这一点,我们需要一个 getter 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 更改为 return int

public int getRadius() {
    return radius;
}

...并修改我们compareTo的:

public int compareTo(final Circle other) {
    if(other == null) {
        return 1;
    } else {
        return radius - other.getRadius();
    }
}
于 2013-08-11T19:05:36.290 回答
2

name是静态的并且为空,因为它从未设置过。我想你误解了 的意思static

于 2013-08-11T18:55:10.260 回答
0

name您的可能Circle不应该是static,您应该在Circle构造函数中为其分配一个值:

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;
    }
}
于 2013-08-11T18:56:36.507 回答
0

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

return name.compareTo(c.name);

被执行,name 有一个空值。您正在尝试通过此空值变量调用方法(compareTo(...)),因此这将导致 NullPointerException 抛出。

此外,将名称设置为静态可能会导致每次创建对象时都会覆盖其值。在所有创建的对象中,静态变量在某种意义上被认为是“唯一的”和“通用的”,因为它们的生命周期贯穿程序的整个运行。更进一步,静态变量存储在计算机内存的不同位置,而不是存储局部变量或对象。

于 2013-08-11T19:35:51.210 回答