如何调用可选对象的Get()方法

时间:2019-03-12 13:55:07

标签: java arraylist java-stream optional

我的任务是实现一个可用于表示点和轨迹的类,以及一个演示该类用法的小程序。

在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() < em> get() (全部用于自我解释),我还实现了两种方法来查找最低和最高点。为此,我使用了 Streams API -但问题是方法必须返回Point对象不是可选。我知道Optional对象有一个 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() 方法的任何指导,以便我可以返回一个点对象而不是可选对象。

我已经将验证添加到方法中,并且通过了提供的单元测试(我的讲师提供了带有分配的一组测试)。但是,伙计们,我会承认。

整个程序的大部分使用的验证是我们为我们创建的验证,其定义如下:

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 :(得分:0)

您可以使用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);
}

答案 1 :(得分:0)

Optional API具有多种方法,可根据可选内容的持有情况来处理所需的结果,包括:

  • (如GBlodgett所述)一种orElse方法,如果可选为空,则返回备用值(通常为“默认”),或者
  • 这里也很有趣-如果您想在orElseThrow为空的情况下引发异常,则Supplier<Throwable>带有Optional
  • 等等等

最简单(但不建议使用)的方法当然是将get链接到您的minmax调用,这将返回{{1} }实例,如果Point为空,则抛出NoSuchElementException

建议的做法是利用Optional API来处理Optionalmin调用未返回任何值的情况。