猿问

在 Java 中使用 Optional 和 lambdas

我正在使用 Java 中的 Optional 和 lambdas 编写代码,并且想知道在以下情况下最好的方法是什么:


public Optional<BObject> readIndexMaybe(String ref) {

    try {

        return Optional.ofNullable(index.read(ref)).map(BObjectBuilder::build);

    } catch (IOException e) {

        LOGGER.error(String.format("Could not read index of ref: %s, error: %s", ref, e));

    }

    return Optional.empty();

}


public Optional<BObject> readMaybe(String ref) {

    Optional<BObject> bObject = readIndexMaybe(ref);

    return bObject.flatMap(boMaybe -> {                <---- HERE

        try {

            LOGGER.debug(String.format("Object read: %s", ref));

            BObject obj = new BObjectBuilder(boMaybe).stream(loadDocumentStream(boMaybe)).build();

            return Optional.of(obj);

        } catch (IOException e) {

            LOGGER.error(String.format("Could not read file with ref: %s, error: %s", ref, e));

        }


        return Optional.empty();

    });

}

Optional<BObject>使用返回 an然后使用它作为返回类型flatMap接收的 lambda 函数会更好,还是在 lambda 内部返回然后只使用会更好:Optional<BObject>nullmap


public Optional<BObject> readIndexMaybe(String ref) {

   try {

       return Optional.ofNullable(index.read(ref)).map(BObjectBuilder::build);

   } catch (IOException e) {

       LOGGER.error(String.format("Could not read index of ref: %s, error: %s", ref, e));

   }

   return Optional.empty();

}


public Optional<BObject> readMaybe(String ref) {

   Optional<BObject> bObject = readIndexMaybe(ref);

   return bObject.map(boMaybe -> {              <--- HERE

       try {

           LOGGER.debug(String.format("Object read: %s", ref));

           return new BObjectBuilder(boMaybe).stream(loadDocumentStream(boMaybe)).build();

       } catch (IOException e) {

           LOGGER.error(String.format("Could not read file with ref: %s, error: %s", ref, e));

       }


       return null;

   });

}

第一种方法对我来说似乎稍微好一点,因为我可能会在其他地方重用 lambda 函数,但它不会返回null但是Optional. 但是,只要我只在一个地方使用它就值得吗?


慕尼黑8549860
浏览 134回答 2
2回答

UYOU

如果您有选择,我建议编写返回Optional而不是 null 的函数,如果无结果是正常且预期的结果。因此,您将使用flatMap调用此类函数。该map操作对于始终返回有效结果的函数很有用。它还将 null 返回转换为 empty Optional,这主要在您需要适应无法更改的返回 null 的代码时有用。通常的建议是提取方法而不是使用多行语句 lambda。然后,在操作中使用简单的 lambda 或方法引用flatMap。此外,对于 try/catch 块,我建议将 try 子句中的代码最小化为仅可以实际抛出您正在捕获的异常的代码,并在 try 语句之外进行其他转换。在这种情况下,我假设index.read(ref)andloadDocumentStream(boMaybe)是可以抛出的语句IOException。请注意,这意味着局部变量需要保存临时结果,并且它可以为空。我认为这没关系。null 处理非常本地化,它允许您将返回的创建合并Optional到单个表达式中。最后,我建议不要对可选项使用后缀“也许”。这令人困惑,并且在示例boMaybe中flatMap操作的 lambda 参数不正确。仅当值存在时才评估该 lambda,因此没有“可能”。应用所有这些建议给出了结果代码:Optional<BObject> readIndex(String ref) {&nbsp; &nbsp; Index i = null;&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; i = index.read(ref);&nbsp; &nbsp; } catch (IOException e) {&nbsp; &nbsp; &nbsp; &nbsp; LOGGER.error(/*...*/);&nbsp; &nbsp; }&nbsp; &nbsp; return Optional.ofNullable(i).map(BObjectBuilder::build);}Optional<BObject> load(BObject bo) {&nbsp; &nbsp; DocStream docStream = null;&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; LOGGER.debug(/*...*/);&nbsp; &nbsp; &nbsp; &nbsp; docStream = loadDocumentStream(bo);&nbsp; &nbsp; } catch (IOException e) {&nbsp; &nbsp; &nbsp; &nbsp; LOGGER.error(/*...*/);&nbsp; &nbsp; }&nbsp; &nbsp; return Optional.ofNullable(docStream)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.map(ds -> new BObjectBuilder(bo).stream(ds).build());}Optional<BObject> read(String ref) {&nbsp; &nbsp; return readIndex(ref).flatMap(bo -> load(bo)); // or this::load}

小唯快跑啊

您可能希望提供一个稳定且安全的 api,这就是您使用 的原因Optional,尽管在您的情况下它会使事情变得有点复杂,因为您需要捕获已检查的异常。我建议这种方法:public Optional<BObject> readIndexMaybe(String ref) {&nbsp; &nbsp;try {&nbsp; &nbsp; &nbsp; &nbsp;return Optional.ofNullable(index.read(ref)).map(BObjectBuilder::build);&nbsp; &nbsp;} catch (IOException e) {&nbsp; &nbsp; &nbsp; &nbsp;LOGGER.error(String.format("Could not read index of ref: %s, error: %s", ref, e));&nbsp; &nbsp;}&nbsp; &nbsp;return Optional.empty();}public Optional<BObject> readMaybe(String ref) {&nbsp; &nbsp;Optional<BObject> bObject = readIndexMaybe(ref);&nbsp; &nbsp;if(!bObject.isPresent()){&nbsp; &nbsp; &nbsp; return bObject; // is same as Optional.empty()&nbsp; &nbsp;}&nbsp; &nbsp;BObject boMaybe = bObject.get();&nbsp; &nbsp;try {&nbsp; &nbsp; &nbsp; LOGGER.debug(String.format("Object read: %s", ref));&nbsp; &nbsp; &nbsp; boMaybe = new BObjectBuilder(boMaybe).stream(loadDocumentStream(boMaybe)).build();&nbsp; &nbsp; &nbsp; return Optional.of(boMaybe);&nbsp; &nbsp;} catch (IOException e) {&nbsp; &nbsp; &nbsp; LOGGER.error(String.format("Could not read file with ref: %s, error: %s", ref, e));&nbsp; &nbsp; &nbsp; return Optional.empty();&nbsp; &nbsp;}}这与您的地图方法非常相似,但我认为它更清楚,因为您没有try-catch内部 lambda。
随时随地看视频慕课网APP

相关分类

Java
我要回答