[英]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)的思想學派,建議你不要使用break
, continue
或濫用例外對某些濫用價值做同樣的事情)。 我相信這里的想法不是你應該使用一些輔助標志變量,而是要明確說明循環的后置條件。 這使得以前推理循環變得易於理解。 顯然使用從理論上說是理性的形式,所以它對未洗過的群眾(比如我自己)不受歡迎。
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
在單獨的變量測試,封裝arraySize
, k
和randomData
中的對象,並創建其讀取從輸入的數據,並返回或者是一個方法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.