Как вызвать метод Get () необязательных объектов - PullRequest
0 голосов
/ 12 марта 2019

У меня есть задача - реализовать классы, которые можно использовать для представления точек и треков, вместе с небольшой программой, демонстрирующей использование классов.

В классе Track я реализовал метод, который читаетданные из файла CSV, анализирует их и добавляет данные в ArrayList : List<Point> track = new ArrayList<> ();

Вот метод readFile () :

// readFile method that creates a sequence of point objects from data in a file, the name of which is supplied as a string parameter
    public void readFile(String test) throws FileNotFoundException {

        // Scanner for specified file
        Scanner input = new Scanner(new File(test));
        int iteration = 0;
        track.clear ();

        //Fetch and parse
        while (input.hasNextLine ())  {
            String newLine = input.nextLine ();
            if (iteration == 0) { iteration++; continue;}
                String delimiter = ",";
                String[] line = newLine.split(delimiter);
            if (line.length != 4) {
                throw new GPSException ("File contains illegal number of values.");
            }
            else {
                ZonedDateTime time  = ZonedDateTime.parse (line[0]);
                double longitude = Double.parseDouble (line[1]);
                double latitude  = Double.parseDouble (line[2]);
                double elevation = Double.parseDouble (line[3]);

                Point newPoint = new Point (time, longitude, latitude, elevation);
                track.add (newPoint);
            }
        }
            input.close ();
        }

Наряду с различными методами, такими как add () , size () и get () (все говорят сами за себя), я также реализую два метода, чтобы найти как самую низкую, так и самую высокую точку.Для этого я использую Streams API - но проблема в том, что методы должны возвращать объекты Point , , а не Необязательно.Я знаю, что у необязательных объектов есть метод get () , который возвращает содержащийся объект, поэтому использование этого исправит наблюдаемую проблему, но я не знаю, как вызвать этот метод с кодомЯ уже написал для функций:

// Lowest point method
    public Optional<Point> lowestPoint() {
        return track.stream().min (Comparator.comparingDouble (Point::getElevation));
    }

    // Highest point method
    public Optional<Point> highestPoint() {
        return track.stream().max (Comparator.comparingDouble (Point::getElevation));
    }

Я также хочу добавить проверку к обоим этим методам, но был бы признателен за любые рекомендации о том, как вызвать get () метод правильно, так что я могу вернуть объект Point вместо необязательного объекта.

Я добавил валидацию к методам, и она прошла предусмотренные модульные тесты (мой лектор предоставил набор тестов с заданием).Но, ребята, я признаю.

Проверка, которая используется в большей части программы, - это та, которую мы создали для нас, и она определяется следующим образом:

public class GPSException extends RuntimeException {
  public GPSException(String message) {
    super(message);
  }

Проблема в том, что, при использовании .get () или .else () для возврата точечного объекта, я все еще сталкиваюсь со всемивиды проблем.Я создал новый экземпляр Point в классе, но экземпляр отклонен.Код выглядит следующим образом:

// Lowest point method
    public Optional<Point> lowestPoint() {
        ZonedDateTime time = ZonedDateTime.now ();
        double longitude = 0;
        double latitude = 0;
        double elevation = 0;
        if (track.size () != 4) {
            throw new GPSException ("Not enough points to compute");
        } else {
            Point lp = new Point (time, longitude, latitude, elevation);
            return track.stream ()
                        .min (Comparator.comparingDouble (Point::getElevation))
                        .orElse (lp);
        }
    }

Я изо всех сил пытаюсь выяснить, что я делаю неправильно.

Ответы [ 2 ]

0 голосов
/ 12 марта 2019

API Optional имеет ряд методов для обработки желаемого результата в зависимости от того, что удерживает необязательный, в том числе:

  • (как упомянуто GBlodgett) метод orElse, который возвращает альтернативное (обычно «по умолчанию») значение, если необязательный параметр пуст, или
  • , что также интересно здесь - orElseThrow, принимающий Supplier<Throwable>, если хотитебросить исключение, если Optional будет пустым,
  • и т. д.и т. д.

Самым простым (но не рекомендуемым) способом, доступным для вас, было бы, конечно, просто связать get с вашими min и max вызовами, которые либо вернут Point instance или бросить NoSuchElementException, если Optional пусто.

Рекомендуется использовать API Optional для обработки случаев, когда ваши вызовы min или max не возвращают значения.

0 голосов
/ 12 марта 2019

Вы можете использовать Optional::orElse для возврата значения по умолчанию:

public Point lowestPoint() {
    return track.stream()
                .min(Comparator.comparingDouble(Point::getElevation))
                .orElse(someDefaultValue);
}

И аналогично для highestPoint:

public Point highestPoint() {
    return track.stream()
                .max(Comparator.comparingDouble(Point::getElevation))
                .orElse(someDefaultValue);
}
...