繁体   English   中英

是创建一个仅在Optional.ifPresentOrElse中使用的类变量,以避免这种做法吗?

[英]is create a class variable just to be used in Optional.ifPresentOrElse a practice to be avoid?

简而言之,我的上下文是:调用一个API,如果我发现某些标头变量,则将其subString返回一个值。 如果没有,我必须返回Response.status。 我已经通过以下代码成功达到了这样的要求:

...
import com.mashape.unirest.*
...
@Controller
public class MainController {
    private final String gmailKey = "XXX";

    private String stringRetorno = "0";

    @ResponseBody
    @GetMapping("/getsessionkey")
    public String getSessionKey() {

        try {

            HttpResponse<String> response = Unirest
                    .post("https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com/apiservices/pricing/v1.0")
                    .header("x-rapidapi-host", "skyscanner-skyscanner-flight-search-v1.p.rapidapi.com")
                    .header("x-rapidapi-key", gmailKey).header("Content-Type", "application/x-www-form-urlencoded")

                    .body("inboundDate=2019-11-25&cabinClass=economy&children=0&infants=0&Country=BR&Currency=BRL&locale=pt-BR&originPlace=GRU-sky&destinationPlace=MCZ-sky&outboundDate=2019-11-19&adults=2")
                    .asString();

            Optional<String> optionalLocation = Optional.ofNullable(response.getHeaders().getFirst("Location"));

            optionalLocation.ifPresentOrElse(l -> stringRetorno = l.substring(l.lastIndexOf("/") + 1),
                    () -> stringRetorno = String.valueOf(response.getStatus()));

        } catch (Exception e) {
            e.printStackTrace();
        }

        return stringRetorno;

    }

我的疑问取决于编码的方式。 我决定不使用if&null链,而是选择使用一种更优雅,更易读的方式与Optional配合使用。 但是,如果我在方法内部创建stringRetorno,则会遇到“在封闭范围内定义的局部变量stringRetorno必须是最终的或实际上是最终的”。

搜索周围,我发现作为解决方案创建stringRetorno作为类变量。

所以我的直截了当的问题是:我正在做一些事情要避免吗? 一些可能无法回答我的问题但非常有用的问题是:

  • 我是否应该比com.mashape.unirest更喜欢其他Java HTTP Client,而com.mashape.unirest可能已经提供了Optional,所以我可以编写更少的详细代码? 我根本不想比较库。 我的重点是结合接收缺少特定键(位置)的响应头的可能性。 而且,如果API提供程序建议的轻量级Unirest迫使我采取变通办法,则可能是另一个提供Optional的库的建议也可以帮助我。

  • 难道不是在Try / Catch块内编写Optional的?

***解决方案

感谢提供的答案

@ResponseBody
@GetMapping("/getsessionkey")
public String getSessionKey() {

    Optional<String> optionalLocation = null;
    HttpResponse<String> response = null;
    try {

        response = Unirest
                .post("https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com/apiservices/pricing/v1.0")
                .header("x-rapidapi-host", "skyscanner-skyscanner-flight-search-v1.p.rapidapi.com")
                .header("x-rapidapi-key", gmailKey).header("Content-Type", "application/x-www-form-urlencoded")

                .body("inboundDate=2019-11-25&cabinClass=economy&children=0&infants=0&Country=BR&Currency=BRL&locale=pt-BR&originPlace=GRU-sky&destinationPlace=MCZ-sky&outboundDate=2019-11-19&adults=2")
                .asString();

        optionalLocation = Optional.ofNullable(response.getHeaders().getFirst("Location"));

    } catch (Exception e) {
        e.printStackTrace();
    }

    return optionalLocation.map(l -> l.substring(l.lastIndexOf("/") + 1))
            .orElse(String.valueOf(response.getStatus()));

}

ifPresentOrElse可能不是您要使用的方法,而是.orElse

return optionalLocation.orElse(String.valueOf(response.getStatus()));

如果可选选项为空,则如果要执行某些操作(例如记录),则需要使用ifPresentOrElse

我在做避免的事情吗?

是。 将变量拉到与其相关的唯一方法之外的形式很差。 而且,实际上,它为您创建了一个线程安全问题-如当前编写的那样,一个使用您的类并允许两个不同的线程调用MainController.getSessionKey()程序由于这个原因很可能无法正确同步。 。 如果它是方法的局部变量,那将是不正确的。

如果该变量是字符串的可变容器 (例如,数组, ListAtomicReference ),则可以使用该方法本地的变量。 然后,容器可以是最终容器,也可以是有效的最终容器,而不会阻止您更改其内容。

但是使用map()orElse()的组合会更清洁,这样您就不需要首先使用lambda来设置字符串引用:

stringRetorno = optionalLocation.map(l -> l.substring(l.lastIndexOf("/") + 1))
        .orElse(String.valueOf(response.getStatus()));
  • 我是否应该比com.mashape.unirest更喜欢其他Java HTTP Client,而com.mashape.unirest可能已经提供了Optional,所以我可以编写更少的详细代码?

也许我误会了,但是我看到的唯一节省代码的地方是删除了Optional.ofNullable()调用(但保留了其参数的等效项)。 这并不是冗长的减少,也不是清晰度的改善。 我认为这样做的潜力不是寻找其他客户的任何理由。

(但是,如果您确实要寻找其他客户端,请不要在这里查看 。有关图书馆和其他场外资源的建议在这里不合时宜。)

  • 难道不是在Try / Catch块内编写Optional的?

不? 也许“压倒性”不是您要查找的术语,但是即使您确实是“过分杀伤”或“过量”或类似的意思,也仍然没有。 我什至看不到你为什么会这样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM