2016-09-24 3 views
3

Прежде всего, позвольте мне пояснить, что я ограничен дизайном API, поэтому, пожалуйста, не изменяйте API, однако частные функции могут быть добавлены.Верните «Компаратор» из другой функции

public class Point implements Comparable<Point> { 

    public Point(int x, int y)    // constructs the point (x, y) 
    public void draw()      // draws this point 
    public void drawTo(Point that)   // draws the line segment from this point to that point 
    public String toString()    // string representation 

    public int compareTo(Point that)  // compare two points by y-coordinates, breaking ties by x-coordinates 
    public double slopeTo(Point that)  // the slope between this point and that point 
    public Comparator<Point> slopeOrder() // compare two points by slopes they make with this point 
} 

Проблема возникает, когда я пытаюсь переопределить функцию сравнения в методе slopeOrder(). Я попытался вызвать метод compare() в функции slopeOrder(), но поскольку у меня нет никаких параметров в API, я не мог.

Просьба предложить некоторые решения для возврата Comparator<Point> из метода slopeOrder().

+0

выглядит как ASM;) с этими комментариями линии;) – Antoniossss

+0

Нужно ли вам называть сравнение? Если точки сопоставимы, зачем вам нужен этот компаратор. Похоже, что компаратор, которого вы должны вернуть, должен определить другой порядок. –

+0

Это одно из заданий на coursera (algs4), прибитое логической частью, но это первый раз, когда я имею дело с интерфейсом Comparator. – Shanky

ответ

1

Вы можете создать экземпляр Comparator<...> с помощью лямбда-выражения:

public Comparator<Point> slopeOrder() { 
    return (a, b) -> { 
     // code here 
    }; 
} 

Здесь a и b являются точками для сравнения.

Или, если вы ниже Java 8, вы должны использовать анонимный класс:

public Comparator<Point> slopeOrder() { 
    return new Comparator<Point>() { 
     @Override 
     public int compare(Point a, Point b) { 
      // code here 
     } 
    }; 
} 

Если Comparator является statless, вы можете создать 1 экземпляр и сохранить его как static final поле, просто возвращайте этот экземпляр.

Конечно, вы также можете пройти долгий путь и создать новый класс, реализующий Comparator<Point>, и вместо этого создать экземпляр этого класса.

+0

Это сработало просто отлично! Я рассмотрю лямбда-выражения. – Shanky

+1

Компараторы всегда * без гражданства *. Этот конкретный компаратор является контекстуальным, т. Е. Он не может быть одиночным, потому что он использует текущую «точку» для вычисления склонов, которые нужно сравнить. – Andreas

0

Вы можете сравнить два очка с this пункт.

public Comparator<Point> slopeOrder() { 
    final Point that = this; 
    return new Comparator<Point>() { 

     public int compare(Point o1, Point o2) { 
      return Double.compare (o1.slopeTo(that) - o2.slopeTo(that)); 
     } 
    }; 
} 
+0

Не используйте 'd1 - d2' для сравнения значений' double'. Используйте 'Double.compare (d1, d2)'. – Andreas

3

Поскольку описание метода slopeOrder() является:

сравнить две точки склонов они делают с этой точки

Это означает, что вам нужно сравнить значение возвращается путем вызова slopeTo(Point that) на каждый объект. Учитывая, что возвращаемое значение этого метода равно double, это означает, что вам необходимо позвонить Double.compare().

В предварительной Java 8, вы бы реализовать его, используя анонимный класс:

public Comparator<Point> slopeOrder() { 
    return new Comparator<Point>() { 
     @Override 
     public int compare(Point o1, Point o2) { 
      return Double.compare(slopeTo(o1), slopeTo(o2)); 
     } 
    }; 
} 

В Java 8, что гораздо проще писать, как лямбда-выражения:

public Comparator<Point> slopeOrder() { 
    return (o1, o2) -> Double.compare(slopeTo(o1), slopeTo(o2)); 
} 

В обоих случаев, звонки slopeTo() производятся на объекте this вызова slopeOrder().