簡體   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