簡體   English   中英

如何從Java中的循環中刪除while(true)?

[英]How can I remove the while(true) from my loop in Java?

我聽說使用while(true)是一種糟糕的編程習慣。

所以,我編寫了以下代碼來從用戶那里獲取一些數字(默認值)。 但是,如果用戶碰巧輸入-1,那么它將退出程序。

如何在沒有片刻(真實)的情況下寫出來? 我可以想到一個條件讓while循環關閉會立即被捕獲而不會繼續直到下一次迭代?

我現在就是這樣的:

 public static void main(String[] args)
    {
        System.out.println("QuickSelect!");

        while (true)
        {
            System.out.println("Enter \"-1\" to quit.");

            int arraySize = 10;
            System.out.print("Enter the size of the array (10): ");
            String line = input.nextLine();
            if (line.matches("\\d+"))
            {
                arraySize = Integer.valueOf(line);
            }

            if (arraySize == -1) break;

            int k = 1;
            System.out.print("Enter the kth smallest element you desire (1): ");
            line = input.nextLine();
            if (line.matches("\\d+"))
            {
                k = Integer.valueOf(k);
            }

            if (k == -1) break;

            List<Integer> randomData = generateRandomData(arraySize, 1, 100);

            quickSelect(randomData, k);
        }
    }

while (true)很好。 收下。

如果你有一個更自然的終止條件,我會說要使用它,但在這種情況下,正如其他答案證明的那樣,擺脫while (true)會使代碼更難理解。

有一個單一入口單一退出(SESE)的思想學派,建議你不要使用breakcontinue或濫用例外對某些濫用價值做同樣的事情)。 我相信這里的想法不是你應該使用一些輔助標志變量,而是要明確說明循環的后置條件。 這使得以前推理循環變得易於理解。 顯然使用從理論上說是理性的形式,所以它對未洗過的群眾(比如我自己)不受歡迎。

public static void main(String[] args) {
    ...
    do {
        ...
        if (arraySize == -1)  {
            ...
            if (k != -1) {
                ...
            }
        }
    } while (arraySze == -1 || k == -1);
    ...
}

真正的代碼會更復雜,您自然會(!)將輸入,輸出和核心“業務”邏輯分開,這樣可以更容易地看到正在發生的事情。

    bool exit = false;
while (!exit) {
    ...
    ...
    if (k == -1) {
        exit = true;            
    }
    else {         
        List <Integer> ....;
        quickselect(.......);
    }
}

但正如之前所說,在這種情況下,while循環是一種有效的用法。 其他選項將簡單地構建在if語句上以檢查boolean和exit。

雖然這樣的循環在技術上不是錯誤的,但有些人會認為它不像以下那樣可讀:

bool complete = false;

while (!complete)
{

    if (arraySize == -1)
    {
        complete = true;
        break;
    }
}

此外,有時候有一個安全循環計數器是一個好主意,它可以檢查以確保循環沒有經過,例如,1億次迭代,或者比循環體預期的大一些數量。 這是一種確保錯誤不會導致程序“掛起”的安全方法。 相反,你可以給用戶一個友好的“我們很抱歉,但你發現了一個錯誤..程序現在將退出..”你將'complete'設置為true並結束程序或執行其他錯誤處理。 我在生產代碼中看過這個,可能會也可能不會是你會使用的東西。

如果你真的不喜歡while(true)你可以隨時for(;;) 我更喜歡后者,因為它似乎不那么多余。

而(true)在這里完全沒問題,因為條件確實是“當用戶不想退出”時!

或者,您可以在一行上提示兩個輸入以簡化邏輯,並使用“q”進行退出:這允許您將循環重構為“while(!line.equals(”q“))”。

問題是你在這個循環中做了很多,而不是將功能分成簡單的方法。

如果要堅持使用過程方法,可以將數組大小和k的讀取移動到單獨的方法中,並使用賦值結果為賦值的事實:

    for (int arraySize; ( arraySize = readArraySize ( input ) ) != -1;) {
        final int k = readKthSmallestElement ( input );

        List<Integer> randomData = generateRandomData(arraySize, 1, 100);

        quickSelect(randomData, k);
    }

然而,這仍然有點難看,並沒有很好的封裝。 因此,而不是具有兩個!= -1在單獨的變量測試,封裝arraySizekrandomData中的對象,並創建其讀取從輸入的數據,並返回或者是一個方法QuickSelect對象或null如果用戶退出:

    for ( QuickSelect select; ( select = readQuickSelect ( input ) ) != null; ) {
        select.generateRandomData();
        select.quickSelect();
    }        

您甚至可能希望進入從輸入創建一系列QuickSelect對象的下一個階段,每個階段都封裝一次迭代的數據:

    for ( QuickSelect select : new QuickSelectReader ( input ) ) {
        select.generateRandomData();
        select.quickSelect();
    }        

其中QuickSelectReader實現Iterable,迭代器具有創建QuickSelect對象的邏輯,該對象封裝了arraySize,k,列表和快速選擇操作。 但這最終會產生比程序變體更多的代碼。

如果我想在其他地方重復使用它,我只會這樣做; 僅僅為了使main()漂亮是不值得的。

還要注意"-1"與正則表達式"\\\\d+"不匹配,所以你確實有一個無限循環。

雖然(true){}在某些場景中非常有用..如果你說錯誤使用,你應該從1000層建築中跳出來....

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM