Having trouble implementing a nested class compara

2019-09-21 05:14发布

问题:

I'm implementing a Point class and trying to use a nested class to implement a comparator, which will compare based on the slope of two points. I'm having trouble implementing such comparator and don't understand how to use it in my main() function.

This is the error message I got when I try to compile it:

Point.java:20: error: non-static variable this cannot be referenced from a static context
       if (Point.this.slopeTo(pt1) > Point.this.slopeTo(pt2)) {
                ^
Point.java:20: error: non-static variable this cannot be referenced from a static context
       if (Point.this.slopeTo(pt1) > Point.this.slopeTo(pt2)) {
                                          ^
Point.java:22: error: non-static variable this cannot be referenced from a static context
       } else if (Point.this.slopeTo(pt1) < Point.this.slopeTo(pt2)) {
                       ^
Point.java:22: error: non-static variable this cannot be referenced from a static context
       } else if (Point.this.slopeTo(pt1) < Point.this.slopeTo(pt2)) {
                                                 ^
4 errors

The following are my codes:

import java.util.Comparator;
import java.lang.Comparable;
import java.util.Arrays;
import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdOut;


public class Point implements Comparable<Point> {
    private final int x;
    private final int y;

    // constructs the point (x, y)
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    private static class bySlope implements Comparator<Point> {
        public int compare(Point pt1, Point pt2) {
            if (Point.this.slopeTo(pt1) > Point.this.slopeTo(pt2)) {
                return 1;
            } else if (Point.this.slopeTo(pt1) < Point.this.slopeTo(pt2)) {
                return -1;
            }
            return 0;
        }
    }

    // draws this point
    public void draw() {
        StdDraw.point(x, y);
    }

    // draws the line segment from this point to that point
    public void drawTo(Point that) {
        StdDraw.line(this.x, this.y, that.x, that.y);
    }

    // string representatio
    public String toString() {
        return "(" + x + ", " + y + ")";
    }

    // compare two points by y-coordinates, breaking ties by x-coordinates
    public int compareTo(Point that) {
        if (this.y > that.y) {
            return 1;
        } else if (this.y < that.y) {
            return -1;
        } else {
            if (this.x > that.x) {
                return 1;
            } else if (this.x < that.x) {
                return -1;
            } else {
                return 0;
            }
        }
    }

    // the slope between this point and that point
    public double slopeTo(Point that) {
        double lineSlope;
        // horizontal line
        if (that.y == this.y && that.x != this.x) {
            lineSlope = (1.0 - 1.0) / 1.0;
        } else if (that.y != this.y && that.x == this.x) {
            lineSlope = Double.POSITIVE_INFINITY;
        } else if (that.y == this.y && that.x == this.x) {
            lineSlope = Double.NEGATIVE_INFINITY;
        } else {
            lineSlope = (that.y - this.y) / (that.x - this.x);
        }
        return lineSlope;
    }

    // compare two points by slopes they make with this point
    public Comparator<Point> slopeOrder() {
        return new bySlope();
    }

    public static void main(String args[]) {
        Point[] myPoints = new Point[3];

        myPoints[0] = new Point(1,2);
        myPoints[1] = new Point(3,4);
        myPoints[2] = new Point(7,8);

        Arrays.sort(myPoints, new Point.bySlope());

        for (int i = 0; i < myPoints.length; i++) {
            StdOut.println(myPoints[i].toString());
        }
    }
}

回答1:

You should provide inner class instance into Arrays.sort to compare points from view of parent class instance. To do it you should not create new instance in main() function, but get it from Point instance.

So, in main function you should use something like this:

Point pivot;
... // set up pivot point here
Arrays.sort(myPoints, pivot.slopeOrder());

Also you should remove "static" from nested class definition so it becomes inner class, that can actually access its parent members:

private class bySlope implements Comparator<Point> {