2010-02-25 192 views
2

因此而改寫一些代碼,我碰到的東西走過的線路:的Java while循環

方法1

while (iter.hasNext()) { 
    Object obj = iter.next(); 
    if (obj instanceof Something) { 
     returnValue = (Something) obj; 
     break; 
    } 
} 

我重新寫了它因爲沒有過多考慮以下(在重新寫入的實際目的是在該方法中的其它邏輯):

方法2

while ((iter.hasNext()) && (returnValue == null)) { 
    Object obj = iter.next(); 
    if (obj instanceof Something) { 
     returnValue = (Something) obj; 
    } 
} 

我個人沒有任何強烈的偏好,也沒有發現任何一種方法都有問題。任何人都可以考慮使用這兩種方法的好處或後果嗎?返回變量returnValue。人們會如何感覺這是否是該方法的最後一塊,並且只是返回?

編輯:所以這裏是我在做什麼:目前這個方法需要一組授權和驗證它們 - 返回一個布爾值。此方法允許分組,因此您可以指定至少一個或全部(即如果至少一個授權有效,則傳遞整個集合)。但是,這種方法不支持授權級別,我正在修改授權級別,以便每個級別都可以指定不同的分組。所有這些只是背景信息......與上面的代碼沒有多大關係 - 使用另一種方法來執行上述代碼塊。

+0

想到這個更多,看着各種答案。看起來使用'break'是首選,因爲它具有更強的含義,稍微(?)更好的表現(少檢查)。 – nevets1219 2010-02-26 17:43:36

回答

9

對我來說,更清晰的就是將其作爲自己的方法來提取;那麼你可以簡單地返回值而不是分配給本地。

while (iter.hasNext()) { 
    Object obj = iter.next(); 
    if (obj instanceof Something) 
     return (Something)obj; 
} 
return null; 

更好的將是一個foreach循環

for (Object o : yourList) 
    if (o instanceof Something) 
     return (Something)o 
return null; 
+2

我想回答這種方式,但只有在原始代碼後面緊跟着一個「return returnValue」纔是等價的。 (我們不知道)。如果它立即返回,你的代碼會更好,儘管所有的小丑可能會抱怨多個返回點(誰不知道這是保持代碼可讀性的指南,而不是從高到低的指令)。 +1假設你是正確的,因爲這個習慣用法主要用於這種方式。 – paxdiablo 2010-02-25 02:18:12

+0

@paxdiablo即使方法中有更多的事情要做,這部分方法可以被提取到它自己的方法中,並從原始方法調用。感謝您的支持;我花了一段時間才知道多個回報點並不是邪惡的。 – 2010-02-25 02:22:05

+0

傻了,我沒有讀過這個問題的最後一段。事實上,這確實是一個很好的答案。 – paxdiablo 2010-02-25 02:25:29

2

一種學派的思想是,方法的最後應該只有一個返回語句/點。

我傾向於在特定情況下使用任何更清晰的東西。

順便說一句:

1)你應該重寫代碼的作品(假設它)?

2)你應該重寫沒有測試的代碼(假設它沒有)?

+0

被重寫的部分是該塊之前的一些邏輯,該塊被重新寫入第二個方法而沒有意圖。我不相信有測試用例:( – nevets1219 2010-02-25 18:31:12

7

我喜歡第一個,因爲它更清楚爲什麼你要跳出循環。它說:「如果這種情況是真的,設置值並打破循環,我們就完成了」。另一個人又花了我一秒鐘左右的時間,但正如你所說,沒有太大的區別。

+0

我認爲明顯的跳躍更好 – 2010-02-25 03:19:08

+1

這就是爲什麼它是次要的和主觀的=) – 2010-02-25 08:31:20

2

這些在這種情況下是等價的,但是如果你想在之後做某事if情況就不再是這種情況了,這往往是這種情況。

性能是一種洗滌,即使它不是,它是一個不相關的微觀優化。關鍵目標應該是可讀性和可維護性。

+0

真的話,... +1 – whiskeysierra 2010-02-25 03:38:41

3

我更喜歡顯式跳轉(無論是break還是return)。我很難闡明爲什麼,但我可以將它與主動與被動語態的寫作相比較。當然,這只是一種風格,但主動閱讀更直接。

1

方法1是它在做什麼更清晰,它打破了循環時obj instanceof Something==true,雖然方法2也是很明顯的。 方法1的另一個小優點是方法2稍微快一點,因爲方法2對每個循環都進行了一次更多的條件檢查,並且它比方法1執行了更多的檢查。如果檢查 花費了超過1分鐘,該怎麼辦?

因此,顯然方法1更好,更易於理解。

+0

+1有效點! – nevets1219 2010-02-25 18:31:54

1

很明顯,第一種形式更好,因爲它不那麼複雜。如果您對returnValue沒有做任何事情,只要您找到匹配項,就可以立即將其退回。

1

我不同意第一種形式顯然更好......返回,中斷和繼續的問題是,它們使代碼更難以重構。這裏給出的例子太簡單了,不需要這樣的操作,但總的來說,將一段複雜的代碼重構爲自己的方法並忽略確保調用者的返回路徑保持有效是非常容易的。這是自動化測試可以提供幫助的地方,但我仍然更喜歡我的大部分檢查來自編譯器。

我採取了詢問循環在做什麼的方法 - 兩件事,它檢查是否存在一個類型爲Fish的對象,並且它使得該對象在循環外部可用。如果我們分開的兩個責任,我們得到:

Object obj = null; 
while (iter.hasNext() && !(obj instanceof Fish)) { 
    obj = iter.next(); 
} 
if (obj instanceof Fish) { 
    returnValue = (Fish) obj; 
} 

我還是不喜歡它... ...也許它的instanceof的或使用對象,甚至只是迭代器的性質,但看起來好看不碼。

+0

現有的邏輯是:如果它是A型,那麼這樣做就是這樣。我是這樣做的,如果它是A型做到這一點,B型做到了,否則就是別的。我將編輯我的問題以包含更多細節。 – nevets1219 2010-02-25 18:34:51

1

編輯完成後,似乎您將遍歷整個列表以檢查各種權限。該代碼將是這樣的:

Object returnValue=null; //Notice in your original code 
while(iter.hasNext()){ 
    Object kind=iter.next() 
    switch(kind.getType()){ 
     case "fish": 
     case "reptile": 
      if(returnValue!=bird|returnValue!=mammal) 
       returnValue=(coldblood) kind; 
      break; 
     case "bird": 
     case "mammal": 
      returnValue=(coldblood) kind; 
      break; 
     case default: 
      //Fall-through 
    } 
} 
return returnValue; 

原來這就是我要說:

  1. 你說你需要實現權限的多層次的,我相信,你將不得不通過整個迭代採集。
  2. 說了這麼多,我推薦使用方法1 - 那就是如果你不得不休息。 break關鍵字更清晰,速度稍快。 (不過少一跳)
+0

不幸的是,只有兩種情況需要檢查,其他所有情況都會被忽略。當以前未使用的方法(不通過Set)不能檢索我正在查找的值時,我會訴諸遍歷Set。 – nevets1219 2010-02-26 17:43:00